#pragma once #include "mkql_builtins_impl_common.h" #include #include "mkql_builtins_codegen.h" #include #include namespace NKikimr { namespace NMiniKQL { struct TUnaryStub { template static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) { return TFunc::Execute(*args); } #ifndef MKQL_DISABLE_CODEGEN template static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) { return GenerateUnaryWithoutCheck(*args, ctx, block, &TFunc::Generate); } #endif }; struct TUnaryWrap { template static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) { return *args ? TFunc::Execute(*args) : NUdf::TUnboxedValuePod(); } #ifndef MKQL_DISABLE_CODEGEN template static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) { return GenerateUnaryWithCheck(*args, ctx, block, &TFunc::Generate); } #endif }; template struct TBinaryWrap { template static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) { if (CheckLeft && !args[0]) return NUdf::TUnboxedValuePod(); if (CheckRight && !args[1]) return NUdf::TUnboxedValuePod(); return TFunc::Execute(args[0], args[1]); } #ifndef MKQL_DISABLE_CODEGEN template static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) { return GenerateBinary(args[0], args[1], ctx, block, &TFunc::Generate); } #endif }; struct TAggregateWrap { template static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) { if (!args[0]) return args[1]; if (!args[1]) return args[0]; return TFunc::Execute(args[0], args[1]); } #ifndef MKQL_DISABLE_CODEGEN template static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) { return GenerateAggregate(args[0], args[1], ctx, block, &TFunc::Generate); } #endif }; struct TAggrCompareWrap { template static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) { const bool a0(args[0]), a1(args[1]); return (a0 && a1) ? TFunc::Execute(args[0], args[1]) : NUdf::TUnboxedValuePod(TFunc::Simple(a0, a1)); } #ifndef MKQL_DISABLE_CODEGEN template static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) { return GenerateCompareAggregate(args[0], args[1], ctx, block, &TFunc::Generate, TFunc::SimplePredicate); } #endif }; template struct TTernaryWrap { template static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod* args) { if (CheckFirst && !*args) return NUdf::TUnboxedValuePod(); return TFunc::Execute(args[0], args[1], args[2]); } #ifndef MKQL_DISABLE_CODEGEN template static Value* Generate(Value *const * args, const TCodegenContext& ctx, BasicBlock*& block) { return GenerateTernary(args[0], args[1], args[2], ctx, block, &TFunc::Generate); } #endif }; template struct TArithmeticConstraintsUnary { static_assert(std::is_arithmetic::value, "Input type must be arithmetic!"); static_assert(std::is_arithmetic::value, "Output type must be arithmetic!"); }; template struct TArithmeticConstraintsSame { static_assert(std::is_arithmetic::value, "Input type must be arithmetic!"); static_assert(std::is_same::value, "Input and output must be same types!"); }; template struct TArithmeticConstraintsBinary { static_assert(std::is_arithmetic::value, "Left type must be arithmetic!"); static_assert(std::is_arithmetic::value, "Right type must be arithmetic!"); static_assert(std::is_arithmetic::value, "Output type must be arithmetic!"); }; template struct TSimpleArithmeticUnary : public TArithmeticConstraintsSame { static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) { return NUdf::TUnboxedValuePod(TImpl::Do(arg.template Get())); } static void DoPtr( const typename TPrimitiveDataType::TLayout* arg, typename TPrimitiveDataType::TLayout* res) { *res = TImpl::Do(*arg); } #ifndef MKQL_DISABLE_CODEGEN static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block) { auto& context = ctx.Codegen.GetContext(); const auto val = GetterFor(arg, context, block); const auto res = TImpl::Gen(val, ctx, block); const auto wide = SetterFor(res, context, block); return wide; } #endif }; template struct TDecimalUnary { static void DoPtr( const NYql::NDecimal::TInt128* arg, NYql::NDecimal::TInt128* res) { *res = TImpl::Execute(NUdf::TUnboxedValuePod(*arg)).GetInt128(); } }; template struct TSimpleArithmeticBinary : public TArithmeticConstraintsBinary { static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) { return NUdf::TUnboxedValuePod(TImpl::Do(left.template Get(), right.template Get())); } static void DoPtr( const typename TPrimitiveDataType::TLayout* left, const typename TPrimitiveDataType::TLayout* right, typename TPrimitiveDataType::TLayout* res) { *res = TImpl::Do(*left, *right); } #ifndef MKQL_DISABLE_CODEGEN static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block) { auto& context = ctx.Codegen.GetContext(); auto lhs = GetterFor(left, context, block); auto rhs = GetterFor(right, context, block); if constexpr (!CustomCast) { lhs = StaticCast(lhs, context, block); rhs = StaticCast(rhs, context, block); } const auto res = TImpl::Gen(lhs, rhs, ctx, block); const auto wide = SetterFor(res, context, block); return wide; } #endif }; template struct TShiftArithmeticBinary : public TArithmeticConstraintsSame { static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& left, const NUdf::TUnboxedValuePod& right) { return NUdf::TUnboxedValuePod(TImpl::Do(left.template Get(), right.Get())); } #ifndef MKQL_DISABLE_CODEGEN static Value* Generate(Value* left, Value* right, const TCodegenContext& ctx, BasicBlock*& block) { auto& context = ctx.Codegen.GetContext(); const auto lhs = GetterFor(left, context, block); const auto rhs = CastInst::Create(Instruction::Trunc, right, Type::getInt8Ty(context), "bits", block); const auto res = TImpl::Gen(lhs, rhs, ctx, block); const auto wide = SetterFor(res, context, block); return wide; } #endif }; template struct TUnaryArgs { static const TFunctionParamMetadata Value[3]; }; template const TFunctionParamMetadata TUnaryArgs::Value[3] = { { TOutput::Id, 0 }, { TInput::Id, 0 }, { 0, 0 } }; template struct TUnaryArgsOpt { static const TFunctionParamMetadata Value[3]; }; template const TFunctionParamMetadata TUnaryArgsOpt::Value[3] = { { TOutput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 }, { TInput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 }, { 0, 0 } }; template struct TUnaryArgsWithNullableResult { static const TFunctionParamMetadata Value[3]; }; template const TFunctionParamMetadata TUnaryArgsWithNullableResult::Value[3] = { { TOutput::Id, TFunctionParamMetadata::FlagIsNullable }, { TInput::Id, 0 }, { 0, 0 } }; template struct TUnaryArgsWithNullableResultOpt { static const TFunctionParamMetadata Value[3]; }; template const TFunctionParamMetadata TUnaryArgsWithNullableResultOpt::Value[3] = { { TOutput::Id, TFunctionParamMetadata::FlagIsNullable }, { TInput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 }, { 0, 0 } }; template struct TBinaryArgs { static const TFunctionParamMetadata Value[4]; }; template const TFunctionParamMetadata TBinaryArgs::Value[4] = { { TOutput::Id, 0 }, { TInput::Id, 0 }, { TInput::Id, 0 }, { 0, 0 } }; template struct TBinaryArgsOpt { static const TFunctionParamMetadata Value[4]; }; template const TFunctionParamMetadata TBinaryArgsOpt::Value[4] = { { TOutput::Id, (IsLeftOptional || IsRightOptional) ? TFunctionParamMetadata::FlagIsNullable : 0 }, { TInput1::Id, IsLeftOptional ? TFunctionParamMetadata::FlagIsNullable : 0 }, { TInput2::Id, IsRightOptional ? TFunctionParamMetadata::FlagIsNullable : 0 }, { 0, 0 } }; template struct TBinaryArgsSameOpt { static const TFunctionParamMetadata Value[4]; }; template const TFunctionParamMetadata TBinaryArgsSameOpt::Value[4] = { { TOutput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 }, { TInput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 }, { TInput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 }, { 0, 0 } }; template struct TBinaryArgsSameOptArgsWithNullableResult { static const TFunctionParamMetadata Value[4]; }; template const TFunctionParamMetadata TBinaryArgsSameOptArgsWithNullableResult::Value[4] = { { TOutput::Id, TFunctionParamMetadata::FlagIsNullable }, { TInput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 }, { TInput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 }, { 0, 0 } }; template struct TBinaryShiftArgs { static const TFunctionParamMetadata Value[4]; }; template const TFunctionParamMetadata TBinaryShiftArgs::Value[4] = { { TOutput::Id, 0 }, { TInput::Id, 0 }, { NUdf::TDataType::Id, 0 }, { 0, 0 } }; template struct TBinaryShiftArgsOpt { static const TFunctionParamMetadata Value[4]; }; template const TFunctionParamMetadata TBinaryShiftArgsOpt::Value[4] = { { TOutput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 }, { TInput::Id, IsOptional ? TFunctionParamMetadata::FlagIsNullable : 0 }, { NUdf::TDataType::Id, 0 }, { 0, 0 } }; template struct TBinaryArgsWithNullableResult { static const TFunctionParamMetadata Value[4]; }; template const TFunctionParamMetadata TBinaryArgsWithNullableResult::Value[4] = { { TOutput::Id, TFunctionParamMetadata::FlagIsNullable }, { TInput::Id, 0 }, { TInput::Id, 0 }, { 0, 0 } }; template struct TTernaryArgs { static const TFunctionParamMetadata Value[5]; }; template const TFunctionParamMetadata TTernaryArgs::Value[5] = { { TOutput::Id, IsResultOptional ? TFunctionParamMetadata::FlagIsNullable : 0}, { TInput1::Id, IsFirstOptional ? TFunctionParamMetadata::FlagIsNullable : 0}, { TInput2::Id, IsSecondOptional ? TFunctionParamMetadata::FlagIsNullable : 0}, { TInput3::Id, IsThirdOptional ? TFunctionParamMetadata::FlagIsNullable : 0}, { 0, 0 } }; template struct TBinaryArgsOptWithNullableResult { static const TFunctionParamMetadata Value[4]; }; template const TFunctionParamMetadata TBinaryArgsOptWithNullableResult::Value[4] = { { TOutput::Id, TFunctionParamMetadata::FlagIsNullable }, { TInput1::Id, IsLeftOptional ? TFunctionParamMetadata::FlagIsNullable : 0 }, { TInput2::Id, IsRightOptional ? TFunctionParamMetadata::FlagIsNullable : 0 }, { 0, 0 } }; template void RegisterFunctionImpl(IBuiltinFunctionRegistry& registry, const std::string_view& name) { #ifndef MKQL_DISABLE_CODEGEN const TFunctionDescriptor description(TArgs::Value, &TWrap::template Execute, reinterpret_cast(&TWrap::template Generate)); #else const TFunctionDescriptor description(TArgs::Value, &TWrap::template Execute); #endif registry.Register(name, description); } template < typename TInput, typename TOutput, template class TFunc, template class TArgs > void RegisterFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterFunctionImpl, TArgs, TUnaryStub>(registry, name); } template < typename TInput, typename TOutput, class TFunc, template class TArgs > void RegisterFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterFunctionImpl, TUnaryStub>(registry, name); RegisterFunctionImpl, TUnaryWrap>(registry, name); } template < typename TType, template class TFunc, template class TArgs > void RegisterCustomAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); RegisterFunctionImpl, TArgs, TAggregateWrap>(registry, name); } template < typename TType, template class TFunc, template class TArgs > void RegisterCustomSameTypesFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); } template < typename TType, template class TFunc, template class TArgs > void RegisterAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); RegisterFunctionImpl, TArgs, TAggregateWrap>(registry, name); } template < typename TType, template class TFunc, template class TArgs > void RegisterAggregateFunctionPoly(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); RegisterFunctionImpl, TArgs, TAggregateWrap>(registry, name); } template < typename TType, template class TFunc, template class TArgs > void RegisterSameTypesFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); } template < typename TInput, typename TOutput, template class TFunc, template class TArgs > void RegisterFunctionUnOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterFunctionImpl, TArgs, TUnaryStub>(registry, name); RegisterFunctionImpl, TArgs, TUnaryWrap>(registry, name); } template < typename TInput1, typename TInput2, typename TOutput, template class TFunc, template class TArgs > void RegisterFunctionBinOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); } template < typename TInput1, typename TInput2, typename TOutput, template class TFunc, template class TArgs > void RegisterFunctionBinPolyOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); } template < template class TFunc, template class TArgs > void RegisterBinaryUnsignedFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); } template < typename TInput, typename TOutput, template class TFunc, template class TArgs > void RegisterShiftFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); RegisterFunctionImpl, TArgs, TBinaryWrap>(registry, name); } template < template class TFunc, template class TArgs > void RegisterUnsignedShiftFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterShiftFunctionOpt, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterShiftFunctionOpt, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterShiftFunctionOpt, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterShiftFunctionOpt, NUdf::TDataType, TFunc, TArgs>(registry, name); } template < template class TFunc, template class TArgs > void RegisterUnaryUnsignedFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterFunctionUnOpt, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionUnOpt, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionUnOpt, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionUnOpt, NUdf::TDataType, TFunc, TArgs>(registry, name); } template < template class TFunc, template class TArgs > void RegisterUnaryIntegralFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterUnaryUnsignedFunctionOpt(registry, name); RegisterFunctionUnOpt, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionUnOpt, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionUnOpt, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionUnOpt, NUdf::TDataType, TFunc, TArgs>(registry, name); } template < template class TFunc, template class TArgs > void RegisterUnaryNumericFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterUnaryIntegralFunctionOpt(registry, name); RegisterFunctionUnOpt, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionUnOpt, NUdf::TDataType, TFunc, TArgs>(registry, name); } template < template class TFunc, template class TArgs > void RegisterBinaryIntegralToUnsignedFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); } template < template class TFunc, template class TArgs > void RegisterBinaryIntegralToSignedFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); } template < template class TFunc, template class TArgs > void RegisterBinaryIntegralFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterBinaryUnsignedFunctionOpt(registry, name); RegisterBinaryIntegralToUnsignedFunctionOpt(registry, name); RegisterBinaryIntegralToSignedFunctionOpt(registry, name); } template < template class TFunc, template class TArgs > void RegisterBinaryRealFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); } template < template class TFunc, template class TArgs > void RegisterBinaryNumericFunctionOpt(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterBinaryIntegralFunctionOpt(registry, name); RegisterBinaryRealFunctionOpt(registry, name); } template < template class TFunc, template class TArgs > void RegisterNumericAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterAggregateFunction, TFunc, TArgs>(registry, name); RegisterAggregateFunction, TFunc, TArgs>(registry, name); RegisterAggregateFunction, TFunc, TArgs>(registry, name); RegisterAggregateFunction, TFunc, TArgs>(registry, name); RegisterAggregateFunction, TFunc, TArgs>(registry, name); RegisterAggregateFunction, TFunc, TArgs>(registry, name); RegisterAggregateFunction, TFunc, TArgs>(registry, name); RegisterAggregateFunction, TFunc, TArgs>(registry, name); RegisterAggregateFunction, TFunc, TArgs>(registry, name); RegisterAggregateFunction, TFunc, TArgs>(registry, name); } template < template class TFunc, template class TArgs > void RegisterDatetimeAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterAggregateFunction, TFunc, TArgs>(registry, name); RegisterAggregateFunction, TFunc, TArgs>(registry, name); RegisterAggregateFunction, TFunc, TArgs>(registry, name); RegisterAggregateFunction, TFunc, TArgs>(registry, name); } template < template class TFunc, template class TArgs > void RegisterBigDateAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterAggregateFunction, TFunc, TArgs>(registry, name); RegisterAggregateFunction, TFunc, TArgs>(registry, name); RegisterAggregateFunction, TFunc, TArgs>(registry, name); RegisterAggregateFunction, TFunc, TArgs>(registry, name); } template < template class TFunc, template class TArgs > void RegisterTzDatetimeAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterAggregateFunction, TFunc, TArgs>(registry, name); RegisterAggregateFunction, TFunc, TArgs>(registry, name); RegisterAggregateFunction, TFunc, TArgs>(registry, name); } template < template class TFunc, template class TArgs > void RegisterDatetimeSameTypesFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterSameTypesFunction, TFunc, TArgs>(registry, name); RegisterSameTypesFunction, TFunc, TArgs>(registry, name); RegisterSameTypesFunction, TFunc, TArgs>(registry, name); RegisterSameTypesFunction, TFunc, TArgs>(registry, name); } template < template class TFunc, template class TArgs > void RegisterTzDatetimeSameTypesFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterSameTypesFunction, TFunc, TArgs>(registry, name); RegisterSameTypesFunction, TFunc, TArgs>(registry, name); RegisterSameTypesFunction, TFunc, TArgs>(registry, name); } template < template class TFunc, template class TArgs > void RegisterBooleanAggregateFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterAggregateFunction, TFunc, TArgs>(registry, name); } template < template class TFunc, template class TArgs > void RegisterBooleanSameTypesFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterSameTypesFunction, TFunc, TArgs>(registry, name); } template < template class TFunc, template class TArgs > void RegisterBinaryRealFunction(IBuiltinFunctionRegistry& registry, const std::string_view& name) { RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); RegisterFunctionBinOpt, NUdf::TDataType, NUdf::TDataType, TFunc, TArgs>(registry, name); } void RegisterAdd(IBuiltinFunctionRegistry& registry); void RegisterAdd(TKernelFamilyMap& kernelFamilyMap); void RegisterAggrAdd(IBuiltinFunctionRegistry& registry); void RegisterSub(IBuiltinFunctionRegistry& registry); void RegisterSub(TKernelFamilyMap& kernelFamilyMap); void RegisterMul(IBuiltinFunctionRegistry& registry); void RegisterMul(TKernelFamilyMap& kernelFamilyMap); void RegisterDiv(IBuiltinFunctionRegistry& registry); void RegisterDiv(TKernelFamilyMap& kernelFamilyMap); void RegisterMod(IBuiltinFunctionRegistry& registry); void RegisterMod(TKernelFamilyMap& kernelFamilyMap); void RegisterIncrement(IBuiltinFunctionRegistry& registry); void RegisterDecrement(IBuiltinFunctionRegistry& registry); void RegisterBitAnd(IBuiltinFunctionRegistry& registry); void RegisterBitOr(IBuiltinFunctionRegistry& registry); void RegisterBitXor(IBuiltinFunctionRegistry& registry); void RegisterShiftLeft(IBuiltinFunctionRegistry& registry); void RegisterShiftRight(IBuiltinFunctionRegistry& registry); void RegisterRotLeft(IBuiltinFunctionRegistry& registry); void RegisterRotRight(IBuiltinFunctionRegistry& registry); void RegisterPlus(IBuiltinFunctionRegistry& registry); void RegisterMinus(IBuiltinFunctionRegistry& registry); void RegisterMinus(TKernelFamilyMap& kernelFamilyMap); void RegisterBitNot(IBuiltinFunctionRegistry& registry); void RegisterCountBits(IBuiltinFunctionRegistry& registry); void RegisterAbs(IBuiltinFunctionRegistry& registry); void RegisterAbs(TKernelFamilyMap& kernelFamilyMap); void RegisterConvert(IBuiltinFunctionRegistry& registry); void RegisterConcat(IBuiltinFunctionRegistry& registry); void RegisterSubstring(IBuiltinFunctionRegistry& registry); void RegisterFind(IBuiltinFunctionRegistry& registry); void RegisterInversePresortString(IBuiltinFunctionRegistry& registry); void RegisterInverseString(IBuiltinFunctionRegistry& registry); void RegisterNanvl(IBuiltinFunctionRegistry& registry); void RegisterByteAt(IBuiltinFunctionRegistry& registry); void RegisterMax(IBuiltinFunctionRegistry& registry); void RegisterMin(IBuiltinFunctionRegistry& registry); void RegisterAggrMax(IBuiltinFunctionRegistry& registry); void RegisterAggrMin(IBuiltinFunctionRegistry& registry); void RegisterWith(IBuiltinFunctionRegistry& registry); enum class EPropagateTz { None, FromLeft, FromRight }; std::shared_ptr AddTzType(bool addTz, const std::shared_ptr& type); std::shared_ptr AddTzType(EPropagateTz propagateTz, const std::shared_ptr& type); template arrow::compute::InputType GetPrimitiveInputArrowType(bool tz = false); arrow::compute::InputType GetPrimitiveInputArrowType(NUdf::EDataSlot slot); template arrow::compute::OutputType GetPrimitiveOutputArrowType(bool tz = false); arrow::compute::OutputType GetPrimitiveOutputArrowType(NUdf::EDataSlot slot); std::shared_ptr ExtractTz(bool isTz, const std::shared_ptr& value); std::shared_ptr ExtractTz(bool isTz, const std::shared_ptr& value); std::shared_ptr WithTz(bool propagateTz, const std::shared_ptr& input, const std::shared_ptr& value); std::shared_ptr WithTz(EPropagateTz propagateTz, const std::shared_ptr& input1, const std::shared_ptr& input2, const std::shared_ptr& value); std::shared_ptr CopyTzImpl(const std::shared_ptr& res, bool propagateTz, const std::shared_ptr& input, arrow::MemoryPool* pool, size_t sizeOf, const std::shared_ptr& outputType); template inline std::shared_ptr CopyTz(const std::shared_ptr& res, bool propagateTz, const std::shared_ptr& input, arrow::MemoryPool* pool) { return CopyTzImpl(res, propagateTz, input, pool, sizeof(TOutput), GetPrimitiveDataType()); } std::shared_ptr CopyTzImpl(const std::shared_ptr& res, EPropagateTz propagateTz, const std::shared_ptr& input1, const std::shared_ptr& input2, arrow::MemoryPool* pool, size_t sizeOf, const std::shared_ptr& outputType); template inline std::shared_ptr CopyTz(const std::shared_ptr& res, EPropagateTz propagateTz, const std::shared_ptr& input1, const std::shared_ptr& input2, arrow::MemoryPool* pool) { return CopyTzImpl(res, propagateTz, input1, input2, pool, sizeof(TOutput), GetPrimitiveDataType()); } std::shared_ptr CopyTzImpl(const std::shared_ptr& res, EPropagateTz propagateTz, const std::shared_ptr& input1, const std::shared_ptr& input2, arrow::MemoryPool* pool, size_t sizeOf, const std::shared_ptr& outputType); template inline std::shared_ptr CopyTz(const std::shared_ptr& res, EPropagateTz propagateTz, const std::shared_ptr& input1, const std::shared_ptr& input2, arrow::MemoryPool* pool) { return CopyTzImpl(res, propagateTz, input1, input2, pool, sizeof(TOutput), GetPrimitiveDataType()); } std::shared_ptr CopyTzImpl(const std::shared_ptr& res, EPropagateTz propagateTz, const std::shared_ptr& input1, const std::shared_ptr& input2, arrow::MemoryPool* pool, size_t sizeOf, const std::shared_ptr& outputType); template inline std::shared_ptr CopyTz(const std::shared_ptr& res, EPropagateTz propagateTz, const std::shared_ptr& input1, const std::shared_ptr& input2, arrow::MemoryPool* pool) { return CopyTzImpl(res, propagateTz, input1, input2, pool, sizeof(TOutput), GetPrimitiveDataType()); } using TPrimitiveDataTypeGetter = std::shared_ptr(*)(); using TPrimitiveDataScalarGetter= arrow::Datum(*)(); using TPrimitiveDataScalarGetterWithMemPool = arrow::Datum(*)(void** result, arrow::MemoryPool*); using TUntypedBinaryScalarFuncPtr = void(*)(const void*, const void*, void*); using TUntypedBinaryArrayFuncPtr = void(*)(const void*, const void*, void*, int64_t length, int64_t offset1, int64_t offset2); using TUntypedBinaryScalarOptFuncPtr = bool(*)(const void*, const void*, void*); using TUntypedBinaryArrayOptFuncPtr = void(*)(const void*, const ui8*, const void*, const ui8*, void*, ui8*, int64_t length, int64_t offset1, int64_t offset2); using TUntypedUnaryScalarFuncPtr = void(*)(const void*, void*); using TUntypedUnaryArrayFuncPtr = void(*)(const void*, void*, int64_t length, int64_t offset); arrow::Status ExecScalarImpl(const arrow::compute::ExecBatch& batch, arrow::Datum* res, TPrimitiveDataTypeGetter typeGetter, TPrimitiveDataScalarGetter scalarGetter, TUntypedUnaryScalarFuncPtr func, bool tz, bool propagateTz); arrow::Status ExecArrayImpl(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res, TUntypedUnaryArrayFuncPtr func, size_t outputSizeOf, TPrimitiveDataTypeGetter outputTypeGetter, bool tz, bool propagateTz); arrow::Status ExecUnaryImpl(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res, TPrimitiveDataTypeGetter typeGetter, TPrimitiveDataScalarGetter scalarGetter, bool tz, bool propagateTz, size_t outputSizeOf, TUntypedUnaryScalarFuncPtr scalarFunc, TUntypedUnaryArrayFuncPtr arrayFunc); arrow::Status ExecScalarScalarImpl(const arrow::compute::ExecBatch& batch, arrow::Datum* res, TPrimitiveDataTypeGetter typeGetter, TPrimitiveDataScalarGetter scalarGetter, TUntypedBinaryScalarFuncPtr func, bool tz1, bool tz2, EPropagateTz propagateTz); arrow::Status ExecScalarArrayImpl(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res, TUntypedBinaryArrayFuncPtr func, size_t outputSizeOf, TPrimitiveDataTypeGetter outputTypeGetter, bool tz1, bool tz2, EPropagateTz propagateTz); arrow::Status ExecArrayScalarImpl(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res, TUntypedBinaryArrayFuncPtr func, size_t outputSizeOf, TPrimitiveDataTypeGetter outputTypeGetter, bool tz1, bool tz2, EPropagateTz propagateTz); arrow::Status ExecArrayArrayImpl(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res, TUntypedBinaryArrayFuncPtr func, size_t outputSizeOf, TPrimitiveDataTypeGetter outputTypeGetter, bool tz1, bool tz2, EPropagateTz propagateTz); arrow::Status ExecBinaryImpl(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res, TPrimitiveDataTypeGetter typeGetter, TPrimitiveDataScalarGetter scalarGetter, bool tz1, bool tz2, EPropagateTz propagateTz, size_t outputSizeOf, TUntypedBinaryScalarFuncPtr scalarScalarFunc, TUntypedBinaryArrayFuncPtr scalarArrayFunc, TUntypedBinaryArrayFuncPtr arrayScalarFunc, TUntypedBinaryArrayFuncPtr arrayArrayFunc); arrow::Status ExecScalarScalarOptImpl(const arrow::compute::ExecBatch& batch, arrow::Datum* res, TPrimitiveDataTypeGetter typeGetter, TPrimitiveDataScalarGetter scalarGetter, TUntypedBinaryScalarOptFuncPtr func, bool tz1, bool tz2, EPropagateTz propagateTz); arrow::Status ExecScalarArrayOptImpl(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res, TUntypedBinaryArrayOptFuncPtr func, size_t outputSizeOf, TPrimitiveDataTypeGetter outputTypeGetter, bool tz1, bool tz2, EPropagateTz propagateTz); arrow::Status ExecArrayScalarOptImpl(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res, TUntypedBinaryArrayOptFuncPtr func, size_t outputSizeOf, TPrimitiveDataTypeGetter outputTypeGetter, bool tz1, bool tz2, EPropagateTz propagateTz); arrow::Status ExecArrayArrayOptImpl(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res, TUntypedBinaryArrayOptFuncPtr func, size_t outputSizeOf, TPrimitiveDataTypeGetter outputTypeGetter, bool tz1, bool tz2, EPropagateTz propagateTz); arrow::Status ExecBinaryOptImpl(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res, TPrimitiveDataTypeGetter typeGetter, TPrimitiveDataScalarGetter scalarGetter, bool tz1, bool tz2, EPropagateTz propagateTz, size_t outputSizeOf, TUntypedBinaryScalarOptFuncPtr scalarScalarFunc, TUntypedBinaryArrayOptFuncPtr scalarArrayFunc, TUntypedBinaryArrayOptFuncPtr arrayScalarFunc, TUntypedBinaryArrayOptFuncPtr arrayArrayFunc); arrow::Status ExecDecimalBinaryOptImpl(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res, TPrimitiveDataTypeGetter typeGetter, TPrimitiveDataScalarGetterWithMemPool scalarGetter, size_t outputSizeOf, TUntypedBinaryScalarOptFuncPtr scalarScalarFunc, TUntypedBinaryArrayOptFuncPtr scalarArrayFunc, TUntypedBinaryArrayOptFuncPtr arrayScalarFunc, TUntypedBinaryArrayOptFuncPtr arrayArrayFunc); arrow::Status ExecDecimalUnaryImpl(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res, TPrimitiveDataTypeGetter typeGetter, TUntypedUnaryScalarFuncPtr scalarFunc, TUntypedUnaryArrayFuncPtr arrayFunc); template struct TBinaryKernelExecs; template struct TBinaryKernelExecs { using TTypedBinaryScalarFuncPtr = void(*)( const typename TPrimitiveDataType::TLayout*, const typename TPrimitiveDataType::TLayout*, typename TPrimitiveDataType::TLayout* ); using TTypedBinaryArrayFuncPtr = void(*)( const typename TPrimitiveDataType::TLayout*, const typename TPrimitiveDataType::TLayout*, typename TPrimitiveDataType::TLayout*, int64_t, int64_t, int64_t ); static void ScalarArrayCore( const typename TPrimitiveDataType::TLayout* val1Ptr, const typename TPrimitiveDataType::TLayout* val2Ptr, typename TPrimitiveDataType::TLayout* resPtr, int64_t length, int64_t offset1, int64_t offset2) { TTypedBinaryScalarFuncPtr func = &TFuncInstance::DoPtr; Y_UNUSED(offset1); val2Ptr += offset2; for (int64_t i = 0; i < length; ++i) { func(val1Ptr, val2Ptr, resPtr); ++val2Ptr; ++resPtr; } } static void ArrayScalarCore( const typename TPrimitiveDataType::TLayout* val1Ptr, const typename TPrimitiveDataType::TLayout* val2Ptr, typename TPrimitiveDataType::TLayout* resPtr, int64_t length, int64_t offset1, int64_t offset2) { TTypedBinaryScalarFuncPtr func = &TFuncInstance::DoPtr; Y_UNUSED(offset2); val1Ptr += offset1; for (int64_t i = 0; i < length; ++i) { func(val1Ptr, val2Ptr, resPtr); ++val1Ptr; ++resPtr; } } static void ArrayArrayCore( const typename TPrimitiveDataType::TLayout* val1Ptr, const typename TPrimitiveDataType::TLayout* val2Ptr, typename TPrimitiveDataType::TLayout* resPtr, int64_t length, int64_t offset1, int64_t offset2) { TTypedBinaryScalarFuncPtr func = &TFuncInstance::DoPtr; val1Ptr += offset1; val2Ptr += offset2; for (int64_t i = 0; i < length; ++i) { func(val1Ptr, val2Ptr, resPtr); ++val1Ptr; ++val2Ptr; ++resPtr; } } static arrow::Status Exec(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res) { TTypedBinaryScalarFuncPtr scalarScalarFunc = &TFuncInstance::DoPtr; TTypedBinaryArrayFuncPtr scalarArrayFunc = &ScalarArrayCore; TTypedBinaryArrayFuncPtr arrayScalarFunc = &ArrayScalarCore; TTypedBinaryArrayFuncPtr arrayArrayFunc = &ArrayArrayCore; return ExecBinaryImpl(kernelCtx, batch, res, &GetPrimitiveDataType, &MakeDefaultScalarDatum, Tz1, Tz2, PropagateTz, sizeof(TOutput), (TUntypedBinaryScalarFuncPtr)scalarScalarFunc, (TUntypedBinaryArrayFuncPtr)scalarArrayFunc, (TUntypedBinaryArrayFuncPtr)arrayScalarFunc, (TUntypedBinaryArrayFuncPtr)arrayArrayFunc); } }; template struct TBinaryKernelOptExecsImpl { using TTypedBinaryScalarOptFuncPtr = bool(*)( const typename TPrimitiveDataType::TLayout* val1Ptr, const typename TPrimitiveDataType::TLayout* val2Ptr, typename TPrimitiveDataType::TLayout* resPtr ); using TTypedBinaryArrayOptFuncPtr = void(*)( const typename TPrimitiveDataType::TLayout* val1Ptr, const ui8* valid1, const typename TPrimitiveDataType::TLayout* val2Ptr, const ui8* valid2, typename TPrimitiveDataType::TLayout* resPtr, ui8* resValid, int64_t length, int64_t offset1, int64_t offset2 ); static bool ScalarScalarCoreOpt( const typename TPrimitiveDataType::TLayout* val1Ptr, const typename TPrimitiveDataType::TLayout* val2Ptr, typename TPrimitiveDataType::TLayout* resPtr) { auto resPod = TFuncInstance::Execute(NUdf::TUnboxedValuePod(*val1Ptr), NUdf::TUnboxedValuePod(*val2Ptr)); if (!resPod) { return false; } *resPtr = resPod.template Get::TLayout>(); return true; } static void ScalarArrayCoreOpt( const typename TPrimitiveDataType::TLayout* val1Ptr, const ui8* valid1, const typename TPrimitiveDataType::TLayout* val2Ptr, const ui8* valid2, typename TPrimitiveDataType::TLayout* resPtr, ui8* resValid, int64_t length, int64_t offset1, int64_t offset2) { val2Ptr += offset2; Y_UNUSED(valid1); Y_UNUSED(offset1); for (int64_t i = 0; i < length; ++i, ++val2Ptr, ++resPtr) { if (!valid2 || arrow::BitUtil::GetBit(valid2, i + offset2)) { auto resPod = TFuncInstance::Execute(NUdf::TUnboxedValuePod(*val1Ptr), NUdf::TUnboxedValuePod(*val2Ptr)); if (resPod) { *resPtr = resPod.template Get::TLayout>(); arrow::BitUtil::SetBit(resValid, i); continue; } } arrow::BitUtil::ClearBit(resValid, i); } } static void ArrayScalarCoreOpt( const typename TPrimitiveDataType::TLayout* val1Ptr, const ui8* valid1, const typename TPrimitiveDataType::TLayout* val2Ptr, const ui8* valid2, typename TPrimitiveDataType::TLayout* resPtr, ui8* resValid, int64_t length, int64_t offset1, int64_t offset2) { val1Ptr += offset1; Y_UNUSED(valid2); Y_UNUSED(offset2); for (int64_t i = 0; i < length; ++i, ++val1Ptr, ++resPtr) { if (!valid1 || arrow::BitUtil::GetBit(valid1, i + offset1)) { auto resPod = TFuncInstance::Execute(NUdf::TUnboxedValuePod(*val1Ptr), NUdf::TUnboxedValuePod(*val2Ptr)); if (resPod) { *resPtr = resPod.template Get::TLayout>(); arrow::BitUtil::SetBit(resValid, i); continue; } } arrow::BitUtil::ClearBit(resValid, i); } } static void ArrayArrayCoreOpt( const typename TPrimitiveDataType::TLayout* val1Ptr, const ui8* valid1, const typename TPrimitiveDataType::TLayout* val2Ptr, const ui8* valid2, typename TPrimitiveDataType::TLayout* resPtr, ui8* resValid, int64_t length, int64_t offset1, int64_t offset2) { val1Ptr += offset1; val2Ptr += offset2; for (int64_t i = 0; i < length; ++i, ++val1Ptr, ++val2Ptr, ++resPtr) { if ((!valid1 || arrow::BitUtil::GetBit(valid1, i + offset1)) && (!valid2 || arrow::BitUtil::GetBit(valid2, i + offset2))) { auto resPod = TFuncInstance::Execute(NUdf::TUnboxedValuePod(*val1Ptr), NUdf::TUnboxedValuePod(*val2Ptr)); if (resPod) { *resPtr = resPod.template Get::TLayout>(); arrow::BitUtil::SetBit(resValid, i); continue; } } arrow::BitUtil::ClearBit(resValid, i); } } }; template struct TBinaryKernelExecs { static arrow::Status Exec(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res) { auto scalarScalarFunc = &TBinaryKernelOptExecsImpl::ScalarScalarCoreOpt; auto scalarArrayFunc = &TBinaryKernelOptExecsImpl::ScalarArrayCoreOpt; auto arrayScalarFunc = &TBinaryKernelOptExecsImpl::ArrayScalarCoreOpt; auto arrayArrayFunc = &TBinaryKernelOptExecsImpl::ArrayArrayCoreOpt; return ExecBinaryOptImpl(kernelCtx, batch, res, &GetPrimitiveDataType, &MakeDefaultScalarDatum, Tz1, Tz2, PropagateTz, sizeof(TOutput), (TUntypedBinaryScalarOptFuncPtr)scalarScalarFunc, (TUntypedBinaryArrayOptFuncPtr)scalarArrayFunc, (TUntypedBinaryArrayOptFuncPtr)arrayScalarFunc, (TUntypedBinaryArrayOptFuncPtr)arrayArrayFunc); } }; class TPlainKernel : public TKernel { public: TPlainKernel(const TKernelFamily& family, const std::vector& argTypes, NUdf::TDataTypeId returnType, std::unique_ptr&& arrowKernel, TKernel::ENullMode nullMode); const arrow::compute::ScalarKernel& GetArrowKernel() const final; std::shared_ptr MakeArrowKernel(const TVector& argTypes, TType* resultType) const final; bool IsPolymorphic() const final; private: const std::unique_ptr ArrowKernel; }; template struct TUnaryKernelExecs { using TTypedUnaryScalarFuncPtr = void(*)( const typename TPrimitiveDataType::TLayout*, typename TPrimitiveDataType::TLayout* ); using TTypedUnaryArrayFuncPtr = void(*)( const typename TPrimitiveDataType::TLayout*, typename TPrimitiveDataType::TLayout*, int64_t, int64_t ); static void ArrayCore( const typename TPrimitiveDataType::TLayout* valPtr, typename TPrimitiveDataType::TLayout* resPtr, int64_t length, int64_t offset) { TTypedUnaryScalarFuncPtr func = &TFuncInstance::DoPtr; valPtr += offset; for (int64_t i = 0; i < length; ++i) { func(valPtr, resPtr); ++valPtr; ++resPtr; } } static arrow::Status Exec(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res) { TTypedUnaryScalarFuncPtr func = &TFuncInstance::DoPtr; TTypedUnaryArrayFuncPtr arrayFunc = &ArrayCore; return ExecUnaryImpl(kernelCtx, batch, res, &GetPrimitiveDataType, &MakeDefaultScalarDatum, Tz, PropagateTz, sizeof(TOutput), (TUntypedUnaryScalarFuncPtr)func, (TUntypedUnaryArrayFuncPtr)arrayFunc); } }; template struct TUnaryDecimalKernelExecs { using TInput = NYql::NDecimal::TInt128; using TOutput = NYql::NDecimal::TInt128; static arrow::Status Exec(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res) { auto func = &TFuncInstance::DoPtr; auto arrayFunc = &TUnaryKernelExecs::ArrayCore; return ExecDecimalUnaryImpl(kernelCtx, batch, res, &GetPrimitiveDataType, (TUntypedUnaryScalarFuncPtr)func, (TUntypedUnaryArrayFuncPtr)arrayFunc); } }; using TStatelessArrayKernelExec = arrow::Status(*)(arrow::compute::KernelContext*, const arrow::compute::ExecBatch&, arrow::Datum*); void AddUnaryKernelImpl(TKernelFamilyBase& owner, NUdf::EDataSlot arg1, NUdf::EDataSlot res, TStatelessArrayKernelExec exec, TKernel::ENullMode nullMode); template class TFunc> void AddUnaryKernel(TKernelFamilyBase& owner) { using TInputLayout = typename TInput::TLayout; using TOutputLayout = typename TOutput::TLayout; static constexpr bool tz = (TInput::Features & NUdf::TzDateType) != 0; static constexpr bool propagateTz = (TOutput::Features & NUdf::TzDateType) != 0; using TFuncInstance = TFunc; using TExecs = TUnaryKernelExecs; AddUnaryKernelImpl(owner, TInput::Slot, TOutput::Slot, &TExecs::Exec, TFuncInstance::NullMode); } template void AddUnaryDecimalKernels(TKernelFamilyBase& owner) { using TExecs = TUnaryDecimalKernelExecs; AddUnaryKernelImpl(owner, NUdf::EDataSlot::Decimal, NUdf::EDataSlot::Decimal, &TExecs::Exec, TKernel::ENullMode::Default); } void AddBinaryKernelImpl(TKernelFamilyBase& owner, NUdf::EDataSlot arg1, NUdf::EDataSlot arg2, NUdf::EDataSlot res, TStatelessArrayKernelExec exec, TKernel::ENullMode nullMode); template class TFunc> void AddBinaryKernel(TKernelFamilyBase& owner) { using TInput1Layout = typename TInput1::TLayout; using TInput2Layout = typename TInput2::TLayout; using TOutputLayout = typename TOutput::TLayout; static constexpr bool tz1 = (TInput1::Features & NUdf::TzDateType) != 0; static constexpr bool tz2 = (TInput2::Features & NUdf::TzDateType) != 0; static constexpr EPropagateTz propagateTz = (TOutput::Features & NUdf::TzDateType) ? ((TInput1::Features & NUdf::TzDateType) ? EPropagateTz::FromLeft : EPropagateTz::FromRight) : EPropagateTz::None; using TFuncInstance = TFunc; using TExecs = TBinaryKernelExecs; AddBinaryKernelImpl(owner, TInput1::Slot, TInput2::Slot, TOutput::Slot, &TExecs::Exec, TFuncInstance::NullMode); } template class TFunc> void AddBinaryKernelPoly(TKernelFamilyBase& owner) { using TInput1Layout = typename TInput1::TLayout; using TInput2Layout = typename TInput2::TLayout; using TOutputLayout = typename TOutput::TLayout; static constexpr bool tz1 = (TInput1::Features & NUdf::TzDateType) != 0; static constexpr bool tz2 = (TInput2::Features & NUdf::TzDateType) != 0; static constexpr EPropagateTz propagateTz = (TOutput::Features & NUdf::TzDateType) ? ((TInput1::Features & NUdf::TzDateType) ? EPropagateTz::FromLeft : EPropagateTz::FromRight) : EPropagateTz::None; using TFuncInstance = TFunc; using TExecs = TBinaryKernelExecs; AddBinaryKernelImpl(owner, TInput1::Slot, TInput2::Slot, TOutput::Slot, &TExecs::Exec, TFuncInstance::NullMode); } template class TFunc> void AddUnaryIntegralKernels(TKernelFamilyBase& owner) { AddUnaryKernel, NUdf::TDataType, TFunc>(owner); AddUnaryKernel, NUdf::TDataType, TFunc>(owner); AddUnaryKernel, NUdf::TDataType, TFunc>(owner); AddUnaryKernel, NUdf::TDataType, TFunc>(owner); AddUnaryKernel, NUdf::TDataType, TFunc>(owner); AddUnaryKernel, NUdf::TDataType, TFunc>(owner); AddUnaryKernel, NUdf::TDataType, TFunc>(owner); AddUnaryKernel, NUdf::TDataType, TFunc>(owner); } template class TFunc> void AddUnaryRealKernels(TKernelFamilyBase& owner) { AddUnaryKernel, NUdf::TDataType, TFunc>(owner); AddUnaryKernel, NUdf::TDataType, TFunc>(owner); } template class TFunc> void AddBinaryIntegralKernels(TKernelFamilyBase& owner) { AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); } template class TFunc> void AddBinaryRealKernels(TKernelFamilyBase& owner) { AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); AddBinaryKernel, NUdf::TDataType, NUdf::TDataType, TFunc>(owner); } template class TFuncForIntegral, template class TFuncForReal> class TBinaryNumericKernelFamily : public TKernelFamilyBase { public: TBinaryNumericKernelFamily() { AddBinaryIntegralKernels(*this); AddBinaryRealKernels(*this); } }; template class TFunc> class TUnaryNumericKernelFamily : public TKernelFamilyBase { public: TUnaryNumericKernelFamily() { AddUnaryIntegralKernels(*this); AddUnaryRealKernels(*this); } }; template class TFunc> void AddBinaryPredicateKernel(TKernelFamilyBase& owner) { AddBinaryKernel, TFunc>(owner); } template class TFunc> void AddBinaryPredicateKernelPoly(TKernelFamilyBase& owner) { AddBinaryKernelPoly, TFunc>(owner); } template class TPred> void AddArithmeticComparisonKernels(TKernelFamilyBase& owner) { AddBinaryPredicateKernel, TPred>(owner); AddBinaryPredicateKernel, TPred>(owner); AddBinaryPredicateKernel, TPred>(owner); AddBinaryPredicateKernel, TPred>(owner); AddBinaryPredicateKernel, TPred>(owner); AddBinaryPredicateKernel, TPred>(owner); AddBinaryPredicateKernel, TPred>(owner); AddBinaryPredicateKernel, TPred>(owner); AddBinaryPredicateKernel, TPred>(owner); AddBinaryPredicateKernel, TPred>(owner); } template class TPred> void AddNumericComparisonKernels(TKernelFamilyBase& owner) { // arithmetic types (integral and floating points) AddArithmeticComparisonKernels, TPred>(owner); AddArithmeticComparisonKernels, TPred>(owner); AddArithmeticComparisonKernels, TPred>(owner); AddArithmeticComparisonKernels, TPred>(owner); AddArithmeticComparisonKernels, TPred>(owner); AddArithmeticComparisonKernels, TPred>(owner); AddArithmeticComparisonKernels, TPred>(owner); AddArithmeticComparisonKernels, TPred>(owner); AddArithmeticComparisonKernels, TPred>(owner); AddArithmeticComparisonKernels, TPred>(owner); // bool can only be compared with itself AddBinaryPredicateKernel, NUdf::TDataType, TPred>(owner); } template class TPred> void AddDateComparisonKernelsForDate(TKernelFamilyBase& owner) { AddBinaryPredicateKernelPoly, NUdf::TDataType, TPred>(owner); AddBinaryPredicateKernelPoly, NUdf::TDataType, TPred>(owner); AddBinaryPredicateKernelPoly, NUdf::TDataType, TPred>(owner); AddBinaryPredicateKernelPoly, NUdf::TDataType, TPred>(owner); AddBinaryPredicateKernelPoly, NUdf::TDataType, TPred>(owner); AddBinaryPredicateKernelPoly, NUdf::TDataType, TPred>(owner); AddBinaryPredicateKernelPoly, NUdf::TDataType, TPred>(owner); AddBinaryPredicateKernelPoly, NUdf::TDataType, TPred>(owner); AddBinaryPredicateKernelPoly, NUdf::TDataType, TPred>(owner); AddBinaryPredicateKernelPoly, NUdf::TDataType, TPred>(owner); AddBinaryPredicateKernelPoly, NUdf::TDataType, TPred>(owner); AddBinaryPredicateKernelPoly, NUdf::TDataType, TPred>(owner); } template class TPred> void AddDateComparisonKernels(TKernelFamilyBase& owner) { AddDateComparisonKernelsForDate(owner); AddDateComparisonKernelsForDate(owner); AddDateComparisonKernelsForDate(owner); AddDateComparisonKernelsForDate(owner); AddDateComparisonKernelsForDate(owner); AddDateComparisonKernelsForDate(owner); AddDateComparisonKernelsForDate(owner); AddDateComparisonKernelsForDate(owner); AddDateComparisonKernelsForDate(owner); AddDateComparisonKernelsForDate(owner); AddDateComparisonKernelsForDate(owner); AddDateComparisonKernelsForDate(owner); // Interval can only be compared with itself AddBinaryPredicateKernelPoly, NUdf::TDataType, TPred>(owner); AddBinaryPredicateKernelPoly, NUdf::TDataType, TPred>(owner); AddBinaryPredicateKernelPoly, NUdf::TDataType, TPred>(owner); AddBinaryPredicateKernelPoly, NUdf::TDataType, TPred>(owner); } class TDecimalKernel : public TKernel { public: struct TKernelState : arrow::compute::KernelState { ui8 Precision; }; TDecimalKernel(const TKernelFamily& family, const std::vector& argTypes, NUdf::TDataTypeId returnType, TStatelessArrayKernelExec exec, TKernel::ENullMode nullMode); const arrow::compute::ScalarKernel& GetArrowKernel() const final; std::shared_ptr MakeArrowKernel(const TVector& argTypes, TType* resultType) const final; bool IsPolymorphic() const final; private: TStatelessArrayKernelExec Exec; }; template class TFuncInstance> struct TDecimalKernelExecs { using TInput1 = NYql::NDecimal::TInt128; using TInput2 = NYql::NDecimal::TInt128; using TOutput = NYql::NDecimal::TInt128; static arrow::Datum ScalarGetter(void** result, arrow::MemoryPool* memory_pool) { std::shared_ptr buffer(ARROW_RESULT(arrow::AllocateBuffer(16, memory_pool))); *result = buffer->mutable_data(); return arrow::Datum(std::make_shared::TScalarResult>(buffer)); } template static arrow::Status ExecImpl(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res) { auto scalarScalarFunc = &TBinaryKernelOptExecsImpl>::ScalarScalarCoreOpt; auto scalarArrayFunc = &TBinaryKernelOptExecsImpl>::ScalarArrayCoreOpt; auto arrayScalarFunc = &TBinaryKernelOptExecsImpl>::ArrayScalarCoreOpt; auto arrayArrayFunc = &TBinaryKernelOptExecsImpl>::ArrayArrayCoreOpt; return ExecDecimalBinaryOptImpl(kernelCtx, batch, res, &GetPrimitiveDataType, &ScalarGetter, sizeof(TOutput), (TUntypedBinaryScalarOptFuncPtr)scalarScalarFunc, (TUntypedBinaryArrayOptFuncPtr)scalarArrayFunc, (TUntypedBinaryArrayOptFuncPtr)arrayScalarFunc, (TUntypedBinaryArrayOptFuncPtr)arrayArrayFunc); } using ExecFunc = arrow::Status(*)(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res) ; template static constexpr auto GenerateTable(std::index_sequence) { return std::array{ExecImpl...}; } static arrow::Status Exec(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res) { ui8 precision = static_cast(kernelCtx->state())->Precision; Y_DEBUG_ABORT_UNLESS(precision >= 1&& precision <= 35); static constexpr auto jumpTable = GenerateTable(std::make_index_sequence<35>{}); return jumpTable[precision-1](kernelCtx, batch, res); } }; template class TFunc> void AddBinaryDecimalKernels(TKernelFamilyBase& owner) { auto type1 = NUdf::GetDataTypeInfo(NUdf::EDataSlot::Decimal).TypeId; auto type2 = type1; auto returnType = type1; std::vector argTypes({ type1, type2 }); using Execs = TDecimalKernelExecs; auto kernel = std::make_unique(owner, argTypes, returnType, &Execs::Exec, TKernel::ENullMode::Default); owner.Adopt(argTypes, returnType, std::move(kernel)); } template struct TDecimalComparisonKernelExecs { using TInput1 = NYql::NDecimal::TInt128; using TInput2 = NYql::NDecimal::TInt128; using TOutput = bool; static arrow::Datum ScalarGetter(void** resMem, arrow::MemoryPool*) { auto result = MakeDefaultScalarDatum(); *resMem = GetPrimitiveScalarValueMutablePtr(*result.scalar()); return result; } static arrow::Status Exec(arrow::compute::KernelContext* kernelCtx, const arrow::compute::ExecBatch& batch, arrow::Datum* res) { auto scalarScalarFunc = &TBinaryKernelOptExecsImpl::ScalarScalarCoreOpt; auto scalarArrayFunc = &TBinaryKernelOptExecsImpl::ScalarArrayCoreOpt; auto arrayScalarFunc = &TBinaryKernelOptExecsImpl::ArrayScalarCoreOpt; auto arrayArrayFunc = &TBinaryKernelOptExecsImpl::ArrayArrayCoreOpt; return ExecDecimalBinaryOptImpl(kernelCtx, batch, res, &GetPrimitiveDataType, &ScalarGetter, sizeof(TOutput), (TUntypedBinaryScalarOptFuncPtr)scalarScalarFunc, (TUntypedBinaryArrayOptFuncPtr)scalarArrayFunc, (TUntypedBinaryArrayOptFuncPtr)arrayScalarFunc, (TUntypedBinaryArrayOptFuncPtr)arrayArrayFunc); } }; template void AddDecimalComparisonKernels(TKernelFamilyBase& owner) { auto type1 = NUdf::GetDataTypeInfo(NUdf::EDataSlot::Decimal).TypeId; auto type2 = type1; auto returnType = NUdf::GetDataTypeInfo(NUdf::EDataSlot::Bool).TypeId; std::vector argTypes({ type1, type2 }); using Execs = TDecimalComparisonKernelExecs; auto kernel = std::make_unique(owner, argTypes, returnType, &Execs::Exec, TKernel::ENullMode::Default); owner.Adopt(argTypes, returnType, std::move(kernel)); } } }