diff options
author | Tony-Romanov <150126326+Tony-Romanov@users.noreply.github.com> | 2024-01-26 15:48:29 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-26 15:48:29 +0100 |
commit | f864ae001c0b8e529a0010792a4bf7482dd2d0e7 (patch) | |
tree | da31e05bb62fd7e4ce612bf86699cc9d86bafcb0 | |
parent | 15383ee647ccd062defa8edd78bf7529abdac295 (diff) | |
download | ydb-f864ae001c0b8e529a0010792a4bf7482dd2d0e7.tar.gz |
Add arithmetic kernels for float & double. (#1291)
* Add real kernels.
* Fix null policy for Div/Mod.
* Add tests.
* Replace boolean null policy on target enum.
20 files changed, 219 insertions, 131 deletions
diff --git a/ydb/library/yql/core/arrow_kernels/registry/ut/registry_ut.cpp b/ydb/library/yql/core/arrow_kernels/registry/ut/registry_ut.cpp index f66c4dbe97a..1b2cf7e3df8 100644 --- a/ydb/library/yql/core/arrow_kernels/registry/ut/registry_ut.cpp +++ b/ydb/library/yql/core/arrow_kernels/registry/ut/registry_ut.cpp @@ -112,6 +112,57 @@ Y_UNIT_TEST_SUITE(TKernelRegistryTest) { }); } + Y_UNIT_TEST(TestAddSubMulOps) { + for (const auto oper : {TKernelRequestBuilder::EBinaryOp::Add, TKernelRequestBuilder::EBinaryOp::Sub, TKernelRequestBuilder::EBinaryOp::Mul}) { + for (const auto slot : {EDataSlot::Int8, EDataSlot::Int16, EDataSlot::Int32, EDataSlot::Int64, EDataSlot::Uint8, EDataSlot::Uint16, EDataSlot::Uint32, EDataSlot::Uint64, EDataSlot::Float, EDataSlot::Double}) { + TestOne([slot, oper](auto& b,auto& ctx) { + const auto blockUint8Type = ctx.template MakeType<TBlockExprType>(ctx.template MakeType<TDataExprType>(EDataSlot::Uint8)); + const auto blockType = ctx.template MakeType<TBlockExprType>(ctx.template MakeType<TDataExprType>(slot)); + return b.AddBinaryOp(oper, blockUint8Type, blockType, blockType); + }); + TestOne([slot, oper](auto& b,auto& ctx) { + const auto blockUint8Type = ctx.template MakeType<TBlockExprType>(ctx.template MakeType<TDataExprType>(EDataSlot::Uint8)); + const auto blockType = ctx.template MakeType<TBlockExprType>(ctx.template MakeType<TDataExprType>(slot)); + return b.AddBinaryOp(oper, blockType, blockUint8Type, blockType); + }); + TestOne([slot, oper](auto& b,auto& ctx) { + const auto blockType = ctx.template MakeType<TBlockExprType>(ctx.template MakeType<TDataExprType>(slot)); + return b.AddBinaryOp(oper, blockType, blockType, blockType); + }); + } + } + } + + Y_UNIT_TEST(TestDivModOps) { + for (const auto oper : {TKernelRequestBuilder::EBinaryOp::Div, TKernelRequestBuilder::EBinaryOp::Mod}) { + for (const auto slot : {EDataSlot::Int8, EDataSlot::Int16, EDataSlot::Int32, EDataSlot::Int64, EDataSlot::Uint8, EDataSlot::Uint16, EDataSlot::Uint32, EDataSlot::Uint64, EDataSlot::Float, EDataSlot::Double}) { + TestOne([slot, oper](auto& b,auto& ctx) { + const auto blockUint8Type = ctx.template MakeType<TBlockExprType>(ctx.template MakeType<TDataExprType>(EDataSlot::Uint8)); + const auto rawType = ctx.template MakeType<TDataExprType>(slot); + const auto blockType = ctx.template MakeType<TBlockExprType>(rawType); + const auto returnType = EDataSlot::Float != slot && EDataSlot::Double != slot ? + ctx.template MakeType<TBlockExprType>(ctx.template MakeType<TOptionalExprType>(rawType)) : blockType; + return b.AddBinaryOp(oper, blockUint8Type, blockType, returnType); + }); + TestOne([slot, oper](auto& b,auto& ctx) { + const auto blockUint8Type = ctx.template MakeType<TBlockExprType>(ctx.template MakeType<TDataExprType>(EDataSlot::Uint8)); + const auto rawType = ctx.template MakeType<TDataExprType>(slot); + const auto blockType = ctx.template MakeType<TBlockExprType>(rawType); + const auto returnType = EDataSlot::Float != slot && EDataSlot::Double != slot ? + ctx.template MakeType<TBlockExprType>(ctx.template MakeType<TOptionalExprType>(rawType)) : blockType; + return b.AddBinaryOp(oper, blockType, blockUint8Type, returnType); + }); + TestOne([slot, oper](auto& b,auto& ctx) { + const auto rawType = ctx.template MakeType<TDataExprType>(slot); + const auto blockType = ctx.template MakeType<TBlockExprType>(rawType); + const auto returnType = EDataSlot::Float != slot && EDataSlot::Double != slot ? + ctx.template MakeType<TBlockExprType>(ctx.template MakeType<TOptionalExprType>(rawType)) : blockType; + return b.AddBinaryOp(oper, blockType, blockType, returnType); + }); + } + } + } + Y_UNIT_TEST(TestSize) { TestOne([](auto& b,auto& ctx) { auto blockStrType = ctx.template MakeType<TBlockExprType>(ctx.template MakeType<TDataExprType>(EDataSlot::String)); @@ -121,17 +172,21 @@ Y_UNIT_TEST_SUITE(TKernelRegistryTest) { } Y_UNIT_TEST(TestMinus) { - TestOne([](auto& b,auto& ctx) { - auto blockInt32Type = ctx.template MakeType<TBlockExprType>(ctx.template MakeType<TDataExprType>(EDataSlot::Int32)); - return b.AddUnaryOp(TKernelRequestBuilder::EUnaryOp::Minus, blockInt32Type, blockInt32Type); - }); + for (const auto slot : {EDataSlot::Int8, EDataSlot::Int16, EDataSlot::Int32, EDataSlot::Int64, EDataSlot::Float, EDataSlot::Double}) { + TestOne([slot](auto& b,auto& ctx) { + const auto blockType = ctx.template MakeType<TBlockExprType>(ctx.template MakeType<TDataExprType>(slot)); + return b.AddUnaryOp(TKernelRequestBuilder::EUnaryOp::Minus, blockType, blockType); + }); + } } Y_UNIT_TEST(TestAbs) { - TestOne([](auto& b,auto& ctx) { - auto blockInt32Type = ctx.template MakeType<TBlockExprType>(ctx.template MakeType<TDataExprType>(EDataSlot::Int32)); - return b.AddUnaryOp(TKernelRequestBuilder::EUnaryOp::Abs, blockInt32Type, blockInt32Type); - }); + for (const auto slot : {EDataSlot::Int8, EDataSlot::Int16, EDataSlot::Int32, EDataSlot::Int64, EDataSlot::Float, EDataSlot::Double}) { + TestOne([slot](auto& b,auto& ctx) { + const auto blockType = ctx.template MakeType<TBlockExprType>(ctx.template MakeType<TDataExprType>(slot)); + return b.AddUnaryOp(TKernelRequestBuilder::EUnaryOp::Abs, blockType, blockType); + }); + } } Y_UNIT_TEST(TestCoalesece) { diff --git a/ydb/library/yql/minikql/arrow/mkql_functions.cpp b/ydb/library/yql/minikql/arrow/mkql_functions.cpp index 92a553136df..4e7be0f3ee5 100644 --- a/ydb/library/yql/minikql/arrow/mkql_functions.cpp +++ b/ydb/library/yql/minikql/arrow/mkql_functions.cpp @@ -160,14 +160,14 @@ bool FindArrowFunction(TStringBuf name, const TArrayRef<TType*>& inputTypes, TTy } bool match = false; - switch (kernel->Family.NullMode) { - case TKernelFamily::ENullMode::Default: + switch (kernel->NullMode) { + case TKernel::ENullMode::Default: match = returnIsOptional == hasOptionals; break; - case TKernelFamily::ENullMode::AlwaysNull: + case TKernel::ENullMode::AlwaysNull: match = returnIsOptional; break; - case TKernelFamily::ENullMode::AlwaysNotNull: + case TKernel::ENullMode::AlwaysNotNull: match = !returnIsOptional; break; } diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins.cpp index afa2ff99c28..a8d53ff1795 100644 --- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins.cpp +++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins.cpp @@ -19,65 +19,6 @@ namespace NMiniKQL { namespace { -class TForeignKernel : public TKernel { -public: - TForeignKernel(const TKernelFamily& family, const std::vector<NUdf::TDataTypeId>& argTypes, NUdf::TDataTypeId returnType, - const std::shared_ptr<arrow::compute::Function>& function) - : TKernel(family, argTypes, returnType) - , Function(function) - , ArrowKernel(ResolveKernel(Function, argTypes)) - {} - - const arrow::compute::ScalarKernel& GetArrowKernel() const final { - return ArrowKernel; - } - -private: - static const arrow::compute::ScalarKernel& ResolveKernel(const std::shared_ptr<arrow::compute::Function>& function, - const std::vector<NUdf::TDataTypeId>& argTypes) { - std::vector<arrow::ValueDescr> args; - for (const auto& t : argTypes) { - args.emplace_back(); - auto slot = NUdf::FindDataSlot(t); - MKQL_ENSURE(slot, "Unexpected data type"); - MKQL_ENSURE(ConvertArrowType(*slot, args.back().type), "Can't get arrow type"); - } - - const auto kernel = ARROW_RESULT(function->DispatchExact(args)); - return *static_cast<const arrow::compute::ScalarKernel*>(kernel); - } - -private: - const std::shared_ptr<arrow::compute::Function> Function; - const arrow::compute::ScalarKernel& ArrowKernel; -}; - -template <typename TInput1, typename TOutput> -void RegisterUnary(const arrow::compute::FunctionRegistry& registry, std::string_view name, TKernelFamilyMap& kernelFamilyMap) { - auto func = ARROW_RESULT(registry.GetFunction(std::string(name))); - - std::vector<NUdf::TDataTypeId> argTypes({ NUdf::TDataType<TInput1>::Id }); - NUdf::TDataTypeId returnType = NUdf::TDataType<TOutput>::Id; - - auto family = std::make_unique<TKernelFamilyBase>(); - family->Adopt(argTypes, returnType, std::make_unique<TForeignKernel>(*family, argTypes, returnType, func)); - - Y_ENSURE(kernelFamilyMap.emplace(TString(name), std::move(family)).second); -} - -template <typename TInput1, typename TInput2, typename TOutput> -void RegisterBinary(const arrow::compute::FunctionRegistry& registry, std::string_view name, TKernelFamilyMap& kernelFamilyMap) { - auto func = ARROW_RESULT(registry.GetFunction(std::string(name))); - - std::vector<NUdf::TDataTypeId> argTypes({ NUdf::TDataType<TInput1>::Id, NUdf::TDataType<TInput2>::Id }); - NUdf::TDataTypeId returnType = NUdf::TDataType<TOutput>::Id; - - auto family = std::make_unique<TKernelFamilyBase>(); - family->Adopt(argTypes, returnType, std::make_unique<TForeignKernel>(*family, argTypes, returnType, func)); - - Y_ENSURE(kernelFamilyMap.emplace(TString(name), std::move(family)).second); -} - void RegisterDefaultOperations(IBuiltinFunctionRegistry& registry, TKernelFamilyMap& kernelFamilyMap) { RegisterAdd(registry); RegisterAdd(kernelFamilyMap); diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_abs.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_abs.cpp index 6be9662115b..d81878aa098 100644 --- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_abs.cpp +++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_abs.cpp @@ -23,6 +23,8 @@ inline T Abs(T v) { template<typename TInput, typename TOutput> struct TAbs : public TSimpleArithmeticUnary<TInput, TOutput, TAbs<TInput, TOutput>> { + static constexpr auto NullMode = TKernel::ENullMode::Default; + static TOutput Do(TInput val) { return Abs<TInput>(val); diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_add.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_add.cpp index f50ef29857e..2c23fedd681 100644 --- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_add.cpp +++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_add.cpp @@ -11,7 +11,7 @@ namespace { template<typename TLeft, typename TRight, typename TOutput> struct TAdd : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TAdd<TLeft, TRight, TOutput>> { - static constexpr bool DefaultNulls = true; + static constexpr auto NullMode = TKernel::ENullMode::Default; static TOutput Do(TOutput left, TOutput right) { @@ -193,7 +193,7 @@ void RegisterAdd(IBuiltinFunctionRegistry& registry) { } void RegisterAdd(TKernelFamilyMap& kernelFamilyMap) { - kernelFamilyMap["Add"] = std::make_unique<TBinaryNumericKernelFamily<TAdd>>(); + kernelFamilyMap["Add"] = std::make_unique<TBinaryNumericKernelFamily<TAdd, TAdd>>(); } void RegisterAggrAdd(IBuiltinFunctionRegistry& registry) { diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_div.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_div.cpp index 880321f8f0b..baea609b5e9 100644 --- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_div.cpp +++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_div.cpp @@ -12,6 +12,8 @@ template<typename TLeft, typename TRight, typename TOutput> struct TDiv : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TDiv<TLeft, TRight, TOutput>> { static_assert(std::is_floating_point<TOutput>::value, "expected floating point"); + static constexpr auto NullMode = TKernel::ENullMode::Default; + static TOutput Do(TOutput left, TOutput right) { return left / right; @@ -29,7 +31,7 @@ template <typename TLeft, typename TRight, typename TOutput> struct TIntegralDiv { static_assert(std::is_integral<TOutput>::value, "integral type expected"); - static constexpr bool DefaultNulls = false; + static constexpr auto NullMode = TKernel::ENullMode::AlwaysNull; static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) { @@ -60,7 +62,7 @@ struct TIntegralDiv { const auto result = PHINode::Create(type, 2, "result", done); result->addIncoming(zero, block); - if (std::is_signed<TOutput>() && sizeof(TOutput) <= sizeof(TLeft)) { + if constexpr (std::is_signed<TOutput>() && sizeof(TOutput) <= sizeof(TLeft)) { const auto min = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lv, ConstantInt::get(lv->getType(), Min<TOutput>()), "min", block); const auto one = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rv, ConstantInt::get(rv->getType(), -1), "one", block); const auto two = BinaryOperator::CreateAnd(min, one, "two", block); @@ -167,7 +169,7 @@ void RegisterDiv(IBuiltinFunctionRegistry& registry) { } void RegisterDiv(TKernelFamilyMap& kernelFamilyMap) { - kernelFamilyMap["Div"] = std::make_unique<TBinaryNumericKernelFamily<TIntegralDiv>>(TKernelFamily::ENullMode::AlwaysNull); + kernelFamilyMap["Div"] = std::make_unique<TBinaryNumericKernelFamily<TIntegralDiv, TDiv>>(); } } // namespace NMiniKQL diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_equals.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_equals.cpp index 806f9152b6b..08695d6ca24 100644 --- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_equals.cpp +++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_equals.cpp @@ -162,7 +162,7 @@ struct TEqualsOp; template<typename TLeft, typename TRight> struct TEqualsOp<TLeft, TRight, bool> : public TEquals<TLeft, TRight, false> { - static constexpr bool DefaultNulls = true; + static constexpr auto NullMode = TKernel::ENullMode::Default; }; template<typename TLeft, typename TRight, bool Aggr> @@ -190,7 +190,7 @@ struct TDiffDateEqualsOp; template<typename TLeft, typename TRight> struct TDiffDateEqualsOp<TLeft, TRight, NUdf::TDataType<bool>> : public TDiffDateEquals<TLeft, TRight, false> { - static constexpr bool DefaultNulls = true; + static constexpr auto NullMode = TKernel::ENullMode::Default; }; template <typename TLeft, typename TRight, bool Aggr> diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_greater.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_greater.cpp index 95bf8db40c7..4177e1c9f6a 100644 --- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_greater.cpp +++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_greater.cpp @@ -155,7 +155,7 @@ struct TGreaterOp; template<typename TLeft, typename TRight> struct TGreaterOp<TLeft, TRight, bool> : public TGreater<TLeft, TRight, false> { - static constexpr bool DefaultNulls = true; + static constexpr auto NullMode = TKernel::ENullMode::Default; }; template<typename TLeft, typename TRight, bool Aggr> @@ -183,7 +183,7 @@ struct TDiffDateGreaterOp; template<typename TLeft, typename TRight> struct TDiffDateGreaterOp<TLeft, TRight, NUdf::TDataType<bool>> : public TDiffDateGreater<TLeft, TRight, false> { - static constexpr bool DefaultNulls = true; + static constexpr auto NullMode = TKernel::ENullMode::Default; }; template<typename TLeft, typename TRight, bool Aggr> diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_greater_or_equal.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_greater_or_equal.cpp index 26b29e75f0e..b1adc30bdfe 100644 --- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_greater_or_equal.cpp +++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_greater_or_equal.cpp @@ -155,7 +155,7 @@ struct TGreaterOrEqualOp; template<typename TLeft, typename TRight> struct TGreaterOrEqualOp<TLeft, TRight, bool> : public TGreaterOrEqual<TLeft, TRight, false> { - static constexpr bool DefaultNulls = true; + static constexpr auto NullMode = TKernel::ENullMode::Default; }; template<typename TLeft, typename TRight, bool Aggr> @@ -183,7 +183,7 @@ struct TDiffDateGreaterOrEqualOp; template<typename TLeft, typename TRight> struct TDiffDateGreaterOrEqualOp<TLeft, TRight, NUdf::TDataType<bool>> : public TDiffDateGreaterOrEqual<TLeft, TRight, false> { - static constexpr bool DefaultNulls = true; + static constexpr auto NullMode = TKernel::ENullMode::Default; }; template<typename TLeft, typename TRight, bool Aggr> diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_impl.h.txt b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_impl.h.txt index 2ec08e84068..9706b680e72 100644 --- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_impl.h.txt +++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_impl.h.txt @@ -866,12 +866,12 @@ struct TBinaryKernelExecsBase { }; template<typename TInput1, typename TInput2, typename TOutput, - typename TFuncInstance, bool DefaultNulls> + typename TFuncInstance, TKernel::ENullMode NullMode> struct TBinaryKernelExecs; template<typename TInput1, typename TInput2, typename TOutput, typename TFuncInstance> -struct TBinaryKernelExecs<TInput1, TInput2, TOutput, TFuncInstance, true> : TBinaryKernelExecsBase<TBinaryKernelExecs<TInput1, TInput2, TOutput, TFuncInstance, true>> +struct TBinaryKernelExecs<TInput1, TInput2, TOutput, TFuncInstance, TKernel::ENullMode::Default> : TBinaryKernelExecsBase<TBinaryKernelExecs<TInput1, TInput2, TOutput, TFuncInstance, TKernel::ENullMode::Default>> { static arrow::Status ExecScalarScalar(arrow::compute::KernelContext*, const arrow::compute::ExecBatch& batch, arrow::Datum* res) { MKQL_ENSURE(batch.values.size() == 2, "Expected 2 args"); @@ -948,7 +948,7 @@ struct TBinaryKernelExecs<TInput1, TInput2, TOutput, TFuncInstance, true> : TBin template<typename TInput1, typename TInput2, typename TOutput, typename TFuncInstance> -struct TBinaryKernelExecs<TInput1, TInput2, TOutput, TFuncInstance, false> : TBinaryKernelExecsBase<TBinaryKernelExecs<TInput1, TInput2, TOutput, TFuncInstance, false>> +struct TBinaryKernelExecs<TInput1, TInput2, TOutput, TFuncInstance, TKernel::ENullMode::AlwaysNull> : TBinaryKernelExecsBase<TBinaryKernelExecs<TInput1, TInput2, TOutput, TFuncInstance, TKernel::ENullMode::AlwaysNull>> { static arrow::Status ExecScalarScalar(arrow::compute::KernelContext*, const arrow::compute::ExecBatch& batch, arrow::Datum* res) { MKQL_ENSURE(batch.values.size() == 2, "Expected 2 args"); @@ -1075,8 +1075,8 @@ struct TBinaryKernelExecs<TInput1, TInput2, TOutput, TFuncInstance, false> : TBi class TPlainKernel : public TKernel { public: - TPlainKernel(const TKernelFamily& family, const std::vector<NUdf::TDataTypeId>& argTypes, NUdf::TDataTypeId returnType, const arrow::compute::ScalarKernel& arrowKernel) - : TKernel(family, argTypes, returnType) + TPlainKernel(const TKernelFamily& family, const std::vector<NUdf::TDataTypeId>& argTypes, NUdf::TDataTypeId returnType, const arrow::compute::ScalarKernel& arrowKernel, TKernel::ENullMode nullMode) + : TKernel(family, argTypes, returnType, nullMode) , ArrowKernel(arrowKernel) { } @@ -1133,8 +1133,18 @@ void AddUnaryKernel(TKernelFamilyBase& owner) { NUdf::TDataTypeId returnType = TOutput::Id; arrow::compute::ScalarKernel k({ GetPrimitiveInputArrowType<TInputLayout>() }, GetPrimitiveOutputArrowType<TOutputLayout>(), &TExecs::Exec); - k.null_handling = owner.NullMode == TKernelFamily::ENullMode::Default ? arrow::compute::NullHandling::INTERSECTION : arrow::compute::NullHandling::COMPUTED_PREALLOCATE; - owner.Adopt(argTypes, returnType, std::make_unique<TPlainKernel>(owner, argTypes, returnType, k)); + switch (TFuncInstance::NullMode) { + case TKernel::ENullMode::Default: + k.null_handling = arrow::compute::NullHandling::INTERSECTION; + break; + case TKernel::ENullMode::AlwaysNull: + k.null_handling = arrow::compute::NullHandling::COMPUTED_PREALLOCATE; + break; + case TKernel::ENullMode::AlwaysNotNull: + k.null_handling = arrow::compute::NullHandling::OUTPUT_NOT_NULL; + break; + } + owner.Adopt(argTypes, returnType, std::make_unique<TPlainKernel>(owner, argTypes, returnType, k, TFuncInstance::NullMode)); } template<typename TInput1, typename TInput2, typename TOutput, @@ -1145,15 +1155,25 @@ void AddBinaryKernel(TKernelFamilyBase& owner) { using TOutputLayout = typename TOutput::TLayout; using TFuncInstance = TFunc<TInput1Layout, TInput2Layout, TOutputLayout>; - using TExecs = TBinaryKernelExecs<TInput1Layout, TInput2Layout, TOutputLayout, TFuncInstance, TFuncInstance::DefaultNulls>; + using TExecs = TBinaryKernelExecs<TInput1Layout, TInput2Layout, TOutputLayout, TFuncInstance, TFuncInstance::NullMode>; std::vector<NUdf::TDataTypeId> argTypes({ TInput1::Id, TInput2::Id }); NUdf::TDataTypeId returnType = TOutput::Id; arrow::compute::ScalarKernel k({ GetPrimitiveInputArrowType<TInput1Layout>(), GetPrimitiveInputArrowType<TInput2Layout>() }, GetPrimitiveOutputArrowType<TOutputLayout>(), &TExecs::Exec); - k.null_handling = owner.NullMode == TKernelFamily::ENullMode::Default ? arrow::compute::NullHandling::INTERSECTION : arrow::compute::NullHandling::COMPUTED_PREALLOCATE; - owner.Adopt(argTypes, returnType, std::make_unique<TPlainKernel>(owner, argTypes, returnType, k)); + switch (TFuncInstance::NullMode) { + case TKernel::ENullMode::Default: + k.null_handling = arrow::compute::NullHandling::INTERSECTION; + break; + case TKernel::ENullMode::AlwaysNull: + k.null_handling = arrow::compute::NullHandling::COMPUTED_PREALLOCATE; + break; + case TKernel::ENullMode::AlwaysNotNull: + k.null_handling = arrow::compute::NullHandling::OUTPUT_NOT_NULL; + break; + } + owner.Adopt(argTypes, returnType, std::make_unique<TPlainKernel>(owner, argTypes, returnType, k, TFuncInstance::NullMode)); } template<typename TInput1, typename TInput2, typename TOutput, @@ -1164,15 +1184,25 @@ void AddBinaryKernelPoly(TKernelFamilyBase& owner) { using TOutputLayout = typename TOutput::TLayout; using TFuncInstance = TFunc<TInput1, TInput2, TOutput>; - using TExecs = TBinaryKernelExecs<TInput1Layout, TInput2Layout, TOutputLayout, TFuncInstance, TFuncInstance::DefaultNulls>; + using TExecs = TBinaryKernelExecs<TInput1Layout, TInput2Layout, TOutputLayout, TFuncInstance, TFuncInstance::NullMode>; std::vector<NUdf::TDataTypeId> argTypes({ TInput1::Id, TInput2::Id }); NUdf::TDataTypeId returnType = TOutput::Id; arrow::compute::ScalarKernel k({ GetPrimitiveInputArrowType<TInput1Layout>(), GetPrimitiveInputArrowType<TInput2Layout>() }, GetPrimitiveOutputArrowType<TOutputLayout>(), &TExecs::Exec); - k.null_handling = owner.NullMode == TKernelFamily::ENullMode::Default ? arrow::compute::NullHandling::INTERSECTION : arrow::compute::NullHandling::COMPUTED_PREALLOCATE; - owner.Adopt(argTypes, returnType, std::make_unique<TPlainKernel>(owner, argTypes, returnType, k)); + switch (TFuncInstance::NullMode) { + case TKernel::ENullMode::Default: + k.null_handling = arrow::compute::NullHandling::INTERSECTION; + break; + case TKernel::ENullMode::AlwaysNull: + k.null_handling = arrow::compute::NullHandling::COMPUTED_PREALLOCATE; + break; + case TKernel::ENullMode::AlwaysNotNull: + k.null_handling = arrow::compute::NullHandling::OUTPUT_NOT_NULL; + break; + } + owner.Adopt(argTypes, returnType, std::make_unique<TPlainKernel>(owner, argTypes, returnType, k, TFuncInstance::NullMode)); } template<template<typename, typename> class TFunc> @@ -1188,6 +1218,12 @@ void AddUnaryIntegralKernels(TKernelFamilyBase& owner) { AddUnaryKernel<NUdf::TDataType<ui64>, NUdf::TDataType<ui64>, TFunc>(owner); } +template<template<typename, typename> class TFunc> +void AddUnaryRealKernels(TKernelFamilyBase& owner) { + AddUnaryKernel<NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc>(owner); + AddUnaryKernel<NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner); +} + template<template<typename, typename, typename> class TFunc> void AddBinaryIntegralKernels(TKernelFamilyBase& owner) { AddBinaryKernel<NUdf::TDataType<ui8>, NUdf::TDataType<ui8>, NUdf::TDataType<ui8>, TFunc>(owner); @@ -1264,22 +1300,70 @@ void AddBinaryIntegralKernels(TKernelFamilyBase& owner) { } template<template<typename, typename, typename> class TFunc> +void AddBinaryRealKernels(TKernelFamilyBase& owner) { + AddBinaryKernel<NUdf::TDataType<i8>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<i8>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<float>, NUdf::TDataType<i8>, NUdf::TDataType<float>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<double>, NUdf::TDataType<i8>, NUdf::TDataType<double>, TFunc>(owner); + + AddBinaryKernel<NUdf::TDataType<ui8>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<ui8>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<float>, NUdf::TDataType<ui8>, NUdf::TDataType<float>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<double>, NUdf::TDataType<ui8>, NUdf::TDataType<double>, TFunc>(owner); + + AddBinaryKernel<NUdf::TDataType<i16>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<i16>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<float>, NUdf::TDataType<i16>, NUdf::TDataType<float>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<double>, NUdf::TDataType<i16>, NUdf::TDataType<double>, TFunc>(owner); + + AddBinaryKernel<NUdf::TDataType<ui16>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<ui16>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<float>, NUdf::TDataType<ui16>, NUdf::TDataType<float>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<double>, NUdf::TDataType<ui16>, NUdf::TDataType<double>, TFunc>(owner); + + AddBinaryKernel<NUdf::TDataType<i32>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<i32>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<float>, NUdf::TDataType<i32>, NUdf::TDataType<float>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<double>, NUdf::TDataType<i32>, NUdf::TDataType<double>, TFunc>(owner); + + AddBinaryKernel<NUdf::TDataType<ui32>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<ui32>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<float>, NUdf::TDataType<ui32>, NUdf::TDataType<float>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<double>, NUdf::TDataType<ui32>, NUdf::TDataType<double>, TFunc>(owner); + + AddBinaryKernel<NUdf::TDataType<i64>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<i64>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<float>, NUdf::TDataType<i64>, NUdf::TDataType<float>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<double>, NUdf::TDataType<i64>, NUdf::TDataType<double>, TFunc>(owner); + + AddBinaryKernel<NUdf::TDataType<ui64>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<ui64>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<float>, NUdf::TDataType<ui64>, NUdf::TDataType<float>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<double>, NUdf::TDataType<ui64>, NUdf::TDataType<double>, TFunc>(owner); + + AddBinaryKernel<NUdf::TDataType<float>, NUdf::TDataType<float>, NUdf::TDataType<float>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<float>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<double>, NUdf::TDataType<float>, NUdf::TDataType<double>, TFunc>(owner); + AddBinaryKernel<NUdf::TDataType<double>, NUdf::TDataType<double>, NUdf::TDataType<double>, TFunc>(owner); +} + +template<template<typename, typename, typename> class TFuncForIntegral, template<typename, typename, typename> class TFuncForReal> class TBinaryNumericKernelFamily : public TKernelFamilyBase { public: - TBinaryNumericKernelFamily(TKernelFamily::ENullMode nullMode = TKernelFamily::ENullMode::Default) - : TKernelFamilyBase(nullMode) + TBinaryNumericKernelFamily() { - AddBinaryIntegralKernels<TFunc>(*this); + AddBinaryIntegralKernels<TFuncForIntegral>(*this); + AddBinaryRealKernels<TFuncForReal>(*this); } }; template<template<typename, typename> class TFunc> class TUnaryNumericKernelFamily : public TKernelFamilyBase { public: - TUnaryNumericKernelFamily(TKernelFamily::ENullMode nullMode = TKernelFamily::ENullMode::Default) - : TKernelFamilyBase(nullMode) + TUnaryNumericKernelFamily() { AddUnaryIntegralKernels<TFunc>(*this); + AddUnaryRealKernels<TFunc>(*this); } }; diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_less.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_less.cpp index 5923d93f7a0..55cc9d2898a 100644 --- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_less.cpp +++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_less.cpp @@ -155,7 +155,7 @@ struct TLessOp; template<typename TLeft, typename TRight> struct TLessOp<TLeft, TRight, bool> : public TLess<TLeft, TRight, false> { - static constexpr bool DefaultNulls = true; + static constexpr auto NullMode = TKernel::ENullMode::Default; }; template<typename TLeft, typename TRight, bool Aggr> @@ -183,7 +183,7 @@ struct TDiffDateLessOp; template<typename TLeft, typename TRight> struct TDiffDateLessOp<TLeft, TRight, NUdf::TDataType<bool>> : public TDiffDateLess<TLeft, TRight, false> { - static constexpr bool DefaultNulls = true; + static constexpr auto NullMode = TKernel::ENullMode::Default; }; template<typename TLeft, typename TRight, bool Aggr> diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_less_or_equal.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_less_or_equal.cpp index 27d5c0d7a3d..0b2d849dee4 100644 --- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_less_or_equal.cpp +++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_less_or_equal.cpp @@ -155,7 +155,7 @@ struct TLessOrEqualOp; template<typename TLeft, typename TRight> struct TLessOrEqualOp<TLeft, TRight, bool> : public TLessOrEqual<TLeft, TRight, false> { - static constexpr bool DefaultNulls = true; + static constexpr auto NullMode = TKernel::ENullMode::Default; }; template<typename TLeft, typename TRight, bool Aggr> @@ -183,7 +183,7 @@ struct TDiffDateLessOrEqualOp; template<typename TLeft, typename TRight> struct TDiffDateLessOrEqualOp<TLeft, TRight, NUdf::TDataType<bool>> : public TDiffDateLessOrEqual<TLeft, TRight, false> { - static constexpr bool DefaultNulls = true; + static constexpr auto NullMode = TKernel::ENullMode::Default; }; template<typename TLeft, typename TRight, bool Aggr> diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_minus.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_minus.cpp index e6f267718c3..738426b7269 100644 --- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_minus.cpp +++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_minus.cpp @@ -7,6 +7,8 @@ namespace { template<typename TInput, typename TOutput> struct TMinus : public TSimpleArithmeticUnary<TInput, TOutput, TMinus<TInput, TOutput>> { + static constexpr auto NullMode = TKernel::ENullMode::Default; + static TOutput Do(TInput val) { return -val; diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mod.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mod.cpp index 6e08f29b5ef..18e696f6c23 100644 --- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mod.cpp +++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mod.cpp @@ -11,6 +11,8 @@ template<typename TLeft, typename TRight, typename TOutput> struct TMod : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TMod<TLeft, TRight, TOutput>> { static_assert(std::is_floating_point<TOutput>::value, "expected floating point"); + static constexpr auto NullMode = TKernel::ENullMode::Default; + static TOutput Do(TOutput left, TOutput right) { return std::fmod(left, right); @@ -30,7 +32,7 @@ template <typename TLeft, typename TRight, typename TOutput> struct TIntegralMod { static_assert(std::is_integral<TOutput>::value, "integral type expected"); - static constexpr bool DefaultNulls = false; + static constexpr auto NullMode = TKernel::ENullMode::AlwaysNull; static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) { @@ -61,7 +63,7 @@ struct TIntegralMod { const auto result = PHINode::Create(type, 2, "result", done); result->addIncoming(zero, block); - if (std::is_signed<TOutput>() && sizeof(TOutput) <= sizeof(TLeft)) { + if constexpr (std::is_signed<TOutput>() && sizeof(TOutput) <= sizeof(TLeft)) { const auto min = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, lv, ConstantInt::get(lv->getType(), Min<TOutput>()), "min", block); const auto one = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, rv, ConstantInt::get(rv->getType(), -1), "one", block); const auto two = BinaryOperator::CreateAnd(min, one, "two", block); @@ -91,7 +93,7 @@ void RegisterMod(IBuiltinFunctionRegistry& registry) { } void RegisterMod(TKernelFamilyMap& kernelFamilyMap) { - kernelFamilyMap["Mod"] = std::make_unique<TBinaryNumericKernelFamily<TIntegralMod>>(TKernelFamily::ENullMode::AlwaysNull); + kernelFamilyMap["Mod"] = std::make_unique<TBinaryNumericKernelFamily<TIntegralMod, TMod>>(); } } // namespace NMiniKQL diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mul.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mul.cpp index 36cd070df6a..6872bed7c12 100644 --- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mul.cpp +++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mul.cpp @@ -10,7 +10,7 @@ namespace { template<typename TLeft, typename TRight, typename TOutput> struct TMul : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TMul<TLeft, TRight, TOutput>> { - static constexpr bool DefaultNulls = true; + static constexpr auto NullMode = TKernel::ENullMode::Default; static TOutput Do(TOutput left, TOutput right) { @@ -98,7 +98,7 @@ void RegisterMul(IBuiltinFunctionRegistry& registry) { } void RegisterMul(TKernelFamilyMap& kernelFamilyMap) { - kernelFamilyMap["Mul"] = std::make_unique<TBinaryNumericKernelFamily<TMul>>(); + kernelFamilyMap["Mul"] = std::make_unique<TBinaryNumericKernelFamily<TMul, TMul>>(); } } // namespace NMiniKQL diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_not_equals.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_not_equals.cpp index 7cd305b76e8..e12df3143a1 100644 --- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_not_equals.cpp +++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_not_equals.cpp @@ -162,7 +162,7 @@ struct TNotEqualsOp; template<typename TLeft, typename TRight> struct TNotEqualsOp<TLeft, TRight, bool> : public TNotEquals<TLeft, TRight, false> { - static constexpr bool DefaultNulls = true; + static constexpr auto NullMode = TKernel::ENullMode::Default; }; template<typename TLeft, typename TRight, bool Aggr> @@ -190,7 +190,7 @@ struct TDiffDateNotEqualsOp; template<typename TLeft, typename TRight> struct TDiffDateNotEqualsOp<TLeft, TRight, NUdf::TDataType<bool>> : public TDiffDateNotEquals<TLeft, TRight, false> { - static constexpr bool DefaultNulls = true; + static constexpr auto NullMode = TKernel::ENullMode::Default; }; template <typename TLeft, typename TRight, bool Aggr> diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_string_kernels.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_string_kernels.cpp index f7a1b20cb8f..acf153fefd9 100644 --- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_string_kernels.cpp +++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_string_kernels.cpp @@ -298,8 +298,8 @@ void AddCompareStringKernel(TKernelFamilyBase& kernelFamily) { NUdf::TDataTypeId returnType = NUdf::TDataType<bool>::Id; arrow::compute::ScalarKernel k({ GetPrimitiveInputArrowType<TInput1>(), GetPrimitiveInputArrowType<TInput2>() }, GetPrimitiveOutputArrowType<TOutput>(), &TExecs::Exec); - k.null_handling = kernelFamily.NullMode == TKernelFamily::ENullMode::Default ? arrow::compute::NullHandling::INTERSECTION : arrow::compute::NullHandling::COMPUTED_PREALLOCATE; - kernelFamily.Adopt(argTypes, returnType, std::make_unique<TPlainKernel>(kernelFamily, argTypes, returnType, k)); + k.null_handling = arrow::compute::NullHandling::INTERSECTION; + kernelFamily.Adopt(argTypes, returnType, std::make_unique<TPlainKernel>(kernelFamily, argTypes, returnType, k, TKernel::ENullMode::Default)); } template<typename TOp> @@ -332,8 +332,8 @@ void AddSizeStringKernel(TKernelFamilyBase& kernelFamily) { NUdf::TDataTypeId returnType = NUdf::TDataType<TOutput>::Id; arrow::compute::ScalarKernel k({ GetPrimitiveInputArrowType<TInput>() }, GetPrimitiveOutputArrowType<TOutput>(), &TExecs::Exec); - k.null_handling = kernelFamily.NullMode == TKernelFamily::ENullMode::Default ? arrow::compute::NullHandling::INTERSECTION : arrow::compute::NullHandling::COMPUTED_PREALLOCATE; - kernelFamily.Adopt(argTypes, returnType, std::make_unique<TPlainKernel>(kernelFamily, argTypes, returnType, k)); + k.null_handling = arrow::compute::NullHandling::INTERSECTION; + kernelFamily.Adopt(argTypes, returnType, std::make_unique<TPlainKernel>(kernelFamily, argTypes, returnType, k, TKernel::ENullMode::Default)); } } // namespace diff --git a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_sub.cpp b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_sub.cpp index 2b04e4ea586..95f2c8cf13c 100644 --- a/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_sub.cpp +++ b/ydb/library/yql/minikql/invoke_builtins/mkql_builtins_sub.cpp @@ -11,7 +11,7 @@ namespace { template<typename TLeft, typename TRight, typename TOutput> struct TSub : public TSimpleArithmeticBinary<TLeft, TRight, TOutput, TSub<TLeft, TRight, TOutput>> { - static constexpr bool DefaultNulls = true; + static constexpr auto NullMode = TKernel::ENullMode::Default; static TOutput Do(TOutput left, TOutput right) { @@ -263,7 +263,7 @@ void RegisterSub(IBuiltinFunctionRegistry& registry) { } void RegisterSub(TKernelFamilyMap& kernelFamilyMap) { - kernelFamilyMap["Sub"] = std::make_unique<TBinaryNumericKernelFamily<TSub>>(); + kernelFamilyMap["Sub"] = std::make_unique<TBinaryNumericKernelFamily<TSub, TSub>>(); } } // namespace NMiniKQL diff --git a/ydb/library/yql/minikql/mkql_function_metadata.cpp b/ydb/library/yql/minikql/mkql_function_metadata.cpp index 2678be3728b..0d9e821b951 100644 --- a/ydb/library/yql/minikql/mkql_function_metadata.cpp +++ b/ydb/library/yql/minikql/mkql_function_metadata.cpp @@ -4,8 +4,8 @@ namespace NKikimr { namespace NMiniKQL { -TKernelFamilyBase::TKernelFamilyBase(ENullMode nullMode, const arrow::compute::FunctionOptions* functionOptions) - : TKernelFamily(nullMode, functionOptions) +TKernelFamilyBase::TKernelFamilyBase(const arrow::compute::FunctionOptions* functionOptions) + : TKernelFamily(functionOptions) {} const TKernel* TKernelFamilyBase::FindKernel(const NUdf::TDataTypeId* argTypes, size_t argTypesCount, NUdf::TDataTypeId returnType) const { diff --git a/ydb/library/yql/minikql/mkql_function_metadata.h b/ydb/library/yql/minikql/mkql_function_metadata.h index c6ecabcfddb..e66b8e9c08c 100644 --- a/ydb/library/yql/minikql/mkql_function_metadata.h +++ b/ydb/library/yql/minikql/mkql_function_metadata.h @@ -56,18 +56,10 @@ class TKernel; class TKernelFamily { public: - enum ENullMode { - Default, - AlwaysNull, - AlwaysNotNull - }; - - const ENullMode NullMode; const arrow::compute::FunctionOptions* FunctionOptions; - TKernelFamily(ENullMode nullMode = ENullMode::Default, const arrow::compute::FunctionOptions* functionOptions = nullptr) - : NullMode(nullMode) - , FunctionOptions(functionOptions) + TKernelFamily(const arrow::compute::FunctionOptions* functionOptions = nullptr) + : FunctionOptions(functionOptions) {} virtual ~TKernelFamily() = default; @@ -77,14 +69,22 @@ public: class TKernel { public: + enum class ENullMode { + Default, + AlwaysNull, + AlwaysNotNull + }; + const TKernelFamily& Family; const std::vector<NUdf::TDataTypeId> ArgTypes; const NUdf::TDataTypeId ReturnType; + const ENullMode NullMode; - TKernel(const TKernelFamily& family, const std::vector<NUdf::TDataTypeId>& argTypes, NUdf::TDataTypeId returnType) + TKernel(const TKernelFamily& family, const std::vector<NUdf::TDataTypeId>& argTypes, NUdf::TDataTypeId returnType, ENullMode nullMode) : Family(family) , ArgTypes(argTypes) , ReturnType(returnType) + , NullMode(nullMode) { } @@ -113,7 +113,7 @@ using TKernelFamilyMap = std::unordered_map<TString, std::unique_ptr<TKernelFami class TKernelFamilyBase : public TKernelFamily { public: - TKernelFamilyBase(ENullMode nullMode = ENullMode::Default, const arrow::compute::FunctionOptions* functionOptions = nullptr); + TKernelFamilyBase(const arrow::compute::FunctionOptions* functionOptions = nullptr); const TKernel* FindKernel(const NUdf::TDataTypeId* argTypes, size_t argTypesCount, NUdf::TDataTypeId returnType) const final; TVector<const TKernel*> GetAllKernels() const final; |