aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony-Romanov <150126326+Tony-Romanov@users.noreply.github.com>2024-01-26 15:48:29 +0100
committerGitHub <noreply@github.com>2024-01-26 15:48:29 +0100
commitf864ae001c0b8e529a0010792a4bf7482dd2d0e7 (patch)
treeda31e05bb62fd7e4ce612bf86699cc9d86bafcb0
parent15383ee647ccd062defa8edd78bf7529abdac295 (diff)
downloadydb-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.
-rw-r--r--ydb/library/yql/core/arrow_kernels/registry/ut/registry_ut.cpp71
-rw-r--r--ydb/library/yql/minikql/arrow/mkql_functions.cpp8
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins.cpp59
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_abs.cpp2
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_add.cpp4
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_div.cpp8
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_equals.cpp4
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_greater.cpp4
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_greater_or_equal.cpp4
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_impl.h.txt120
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_less.cpp4
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_less_or_equal.cpp4
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_minus.cpp2
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mod.cpp8
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_mul.cpp4
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_not_equals.cpp4
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_string_kernels.cpp8
-rw-r--r--ydb/library/yql/minikql/invoke_builtins/mkql_builtins_sub.cpp4
-rw-r--r--ydb/library/yql/minikql/mkql_function_metadata.cpp4
-rw-r--r--ydb/library/yql/minikql/mkql_function_metadata.h24
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;