mkql_builtins_minus.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. #include "mkql_builtins_decimal.h" // Y_IGNORE
  2. namespace NKikimr {
  3. namespace NMiniKQL {
  4. namespace {
  5. template<typename TInput, typename TOutput>
  6. struct TMinus : public TSimpleArithmeticUnary<TInput, TOutput, TMinus<TInput, TOutput>> {
  7. static constexpr auto NullMode = TKernel::ENullMode::Default;
  8. static TOutput Do(TInput val)
  9. {
  10. return -val;
  11. }
  12. #ifndef MKQL_DISABLE_CODEGEN
  13. static Value* Gen(Value* arg, const TCodegenContext&, BasicBlock*& block)
  14. {
  15. if constexpr (std::is_integral<TInput>())
  16. return BinaryOperator::CreateNeg(arg, "neg", block);
  17. else
  18. return UnaryOperator::CreateFNeg(arg, "neg", block);
  19. }
  20. #endif
  21. };
  22. struct TDecimalMinus: TDecimalUnary<TDecimalMinus> {
  23. static NUdf::TUnboxedValuePod Execute(const NUdf::TUnboxedValuePod& arg) {
  24. const auto v = arg.GetInt128();
  25. return NYql::NDecimal::IsComparable(v) ? NUdf::TUnboxedValuePod(-v) : arg;
  26. }
  27. #ifndef MKQL_DISABLE_CODEGEN
  28. static Value* Generate(Value* arg, const TCodegenContext& ctx, BasicBlock*& block)
  29. {
  30. const auto val = GetterForInt128(arg, block);
  31. const auto ok = NDecimal::GenIsComparable(val, ctx.Codegen.GetContext(), block);
  32. const auto neg = BinaryOperator::CreateNeg(val, "neg", block);
  33. const auto res = SelectInst::Create(ok, SetterForInt128(neg, block), arg, "result", block);
  34. return res;
  35. }
  36. #endif
  37. };
  38. }
  39. void RegisterMinus(IBuiltinFunctionRegistry& registry) {
  40. RegisterUnaryNumericFunctionOpt<TMinus, TUnaryArgsOpt>(registry, "Minus");
  41. NDecimal::RegisterUnaryFunction<TDecimalMinus, TUnaryArgsOpt>(registry, "Minus");
  42. RegisterFunctionUnOpt<NUdf::TDataType<NUdf::TInterval>, NUdf::TDataType<NUdf::TInterval>, TMinus, TUnaryArgsOpt>(registry, "Minus");
  43. RegisterFunctionUnOpt<NUdf::TDataType<NUdf::TInterval64>, NUdf::TDataType<NUdf::TInterval64>, TMinus, TUnaryArgsOpt>(registry, "Minus");
  44. }
  45. void RegisterMinus(TKernelFamilyMap& kernelFamilyMap) {
  46. auto family = std::make_unique<TUnaryNumericKernelFamily<TMinus>>();
  47. AddUnaryDecimalKernels<TDecimalMinus>(*family);
  48. kernelFamilyMap["Minus"] = std::move(family);
  49. }
  50. } // namespace NMiniKQL
  51. } // namespace NKikimr