#pragma once #include "mkql_builtins_impl.h" // Y_IGNORE // Y_IGNORE namespace NKikimr { namespace NMiniKQL { using TScaledDate = i64; constexpr TScaledDate DateScale = 86400000000ll; constexpr TScaledDate DatetimeScale = 1000000ll; template inline TScaledDate ToScaledDate(typename TSrc::TLayout src); template inline typename TDst::TLayout FromScaledDate(TScaledDate src); template<> inline TScaledDate ToScaledDate>(typename NUdf::TDataType::TLayout src) { return src * DateScale; } template<> inline NUdf::TDataType::TLayout FromScaledDate>(TScaledDate src) { return src / DateScale; } template<> inline TScaledDate ToScaledDate>(typename NUdf::TDataType::TLayout src) { return src * DatetimeScale; } template<> inline NUdf::TDataType::TLayout FromScaledDate>(TScaledDate src) { return src / DatetimeScale; } template<> inline TScaledDate ToScaledDate>(typename NUdf::TDataType::TLayout src) { return src; } template<> inline NUdf::TDataType::TLayout FromScaledDate>(TScaledDate src) { return src; } template<> inline TScaledDate ToScaledDate>(typename NUdf::TDataType::TLayout src) { return src; } template<> inline NUdf::TDataType::TLayout FromScaledDate>(TScaledDate src) { return src; } template<> inline TScaledDate ToScaledDate>(typename NUdf::TDataType::TLayout src) { return src * DateScale; } template<> inline NUdf::TDataType::TLayout FromScaledDate>(TScaledDate src) { return src / DateScale; } template<> inline TScaledDate ToScaledDate>(typename NUdf::TDataType::TLayout src) { return src * DatetimeScale; } template<> inline NUdf::TDataType::TLayout FromScaledDate>(TScaledDate src) { return src / DatetimeScale; } template<> inline TScaledDate ToScaledDate>(typename NUdf::TDataType::TLayout src) { return src; } template<> inline NUdf::TDataType::TLayout FromScaledDate>(TScaledDate src) { return src; } template<> inline TScaledDate ToScaledDate>(typename NUdf::TDataType::TLayout src) { return src * DateScale; } template<> inline NUdf::TDataType::TLayout FromScaledDate>(TScaledDate src) { return src / DateScale; } template<> inline TScaledDate ToScaledDate>(typename NUdf::TDataType::TLayout src) { return src * DatetimeScale; } template<> inline NUdf::TDataType::TLayout FromScaledDate>(TScaledDate src) { return src / DatetimeScale; } template<> inline TScaledDate ToScaledDate>(typename NUdf::TDataType::TLayout src) { return src; } template<> inline NUdf::TDataType::TLayout FromScaledDate>(TScaledDate src) { return src; } template<> inline TScaledDate ToScaledDate>(typename NUdf::TDataType::TLayout src) { return src * DateScale; } template<> inline NUdf::TDataType::TLayout FromScaledDate>(TScaledDate src) { return src / DateScale; } template<> inline TScaledDate ToScaledDate>(typename NUdf::TDataType::TLayout src) { return src * DatetimeScale; } template<> inline NUdf::TDataType::TLayout FromScaledDate>(TScaledDate src) { return src / DatetimeScale; } template<> inline TScaledDate ToScaledDate>(typename NUdf::TDataType::TLayout src) { return src; } template<> inline NUdf::TDataType::TLayout FromScaledDate>(TScaledDate src) { return src; } template<> inline TScaledDate ToScaledDate>(typename NUdf::TDataType::TLayout src) { return src; } template<> inline NUdf::TDataType::TLayout FromScaledDate>(TScaledDate src) { return src; } template inline bool IsBadDateTime(TScaledDate val) { static_assert(TDateType::Features & (NYql::NUdf::DateType | NYql::NUdf::TzDateType), "Date type expected"); if constexpr (TDateType::Features & NYql::NUdf::BigDateType) { return val < NUdf::MIN_TIMESTAMP64 || val > NUdf::MAX_TIMESTAMP64; } else { return val < 0 || val >= TScaledDate(NUdf::MAX_TIMESTAMP); } } template inline bool IsBadInterval(TScaledDate val) { static_assert(TDateType::Features & NYql::NUdf::TimeIntervalType, "Interval type expected"); if constexpr (TDateType::Features & NYql::NUdf::BigDateType) { return val < -NUdf::MAX_INTERVAL64 || val > NUdf::MAX_INTERVAL64; } else { return val <= -TScaledDate(NUdf::MAX_TIMESTAMP) || val >= TScaledDate(NUdf::MAX_TIMESTAMP); } } template inline bool IsBadScaledDate(TScaledDate val) { if constexpr (TDateType::Features & NYql::NUdf::TimeIntervalType) { return IsBadInterval(val); } else { return IsBadDateTime(val); } } #ifndef MKQL_DISABLE_CODEGEN template inline Value* GenIsInt64Overflow(Value* value, LLVMContext &context, BasicBlock* block) { if constexpr (std::is_same_v) { const auto i64Max = ConstantInt::get(value->getType(), static_cast(std::numeric_limits::max())); return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_UGT, value, i64Max, "ugt", block); } else { return ConstantInt::getFalse(context); } } template inline Value* GenIsBadDateTime(Value* val, LLVMContext &context, BasicBlock* block) { static_assert(TDateType::Features & (NYql::NUdf::DateType | NYql::NUdf::TzDateType), "Date type expected"); if constexpr (TDateType::Features & NYql::NUdf::BigDateType) { auto lt = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, val, ConstantInt::get(Type::getInt64Ty(context), NUdf::MIN_TIMESTAMP64), "lt", block); auto ge = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGT, val, ConstantInt::get(Type::getInt64Ty(context), NUdf::MAX_TIMESTAMP64), "ge", block); return BinaryOperator::CreateOr(lt, ge, "or", block); } else { auto lt = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLT, val, ConstantInt::get(Type::getInt64Ty(context), 0), "lt", block); auto ge = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGE, val, ConstantInt::get(Type::getInt64Ty(context), NUdf::MAX_TIMESTAMP), "ge", block); return BinaryOperator::CreateOr(lt, ge, "or", block); } } template inline Value* GenIsBadInterval(Value* val, LLVMContext &context, BasicBlock* block) { static_assert(TDateType::Features & NYql::NUdf::TimeIntervalType, "Interval type expected"); constexpr i64 lowerBound = (TDateType::Features & NYql::NUdf::BigDateType) ? (-NUdf::MAX_INTERVAL64 - 1) : -(i64)NUdf::MAX_TIMESTAMP; constexpr i64 upperBound = (TDateType::Features & NYql::NUdf::BigDateType) ? (NUdf::MAX_INTERVAL64 + 1) : (i64)NUdf::MAX_TIMESTAMP; auto le = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SLE, val, ConstantInt::get(Type::getInt64Ty(context), lowerBound), "le", block); auto ge = CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_SGE, val, ConstantInt::get(Type::getInt64Ty(context), upperBound), "ge", block); return BinaryOperator::CreateOr(le, ge, "or", block); } template inline Value* GenIsBadScaledDate(Value* val, LLVMContext &context, BasicBlock* block) { if constexpr (TDateType::Features & NYql::NUdf::TimeIntervalType) { return GenIsBadInterval(val, context, block); } else { return GenIsBadDateTime(val, context, block); } } template inline Value* GenToScaledDate(Value* value, LLVMContext &context, BasicBlock* block); template inline Value* GenFromScaledDate(Value* value, LLVMContext &context, BasicBlock* block); template<> inline Value* GenToScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { const auto cast = StaticCast::TLayout, TScaledDate>(value, context, block); const auto mul = BinaryOperator::CreateMul(cast, ConstantInt::get(cast->getType(), DateScale), "mul", block); return mul; } template<> inline Value* GenFromScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { const auto div = BinaryOperator::CreateSDiv(value, ConstantInt::get(value->getType(), DateScale), "div", block); const auto cast = StaticCast::TLayout>(div, context, block); return cast; } template<> inline Value* GenToScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { const auto cast = StaticCast::TLayout, TScaledDate>(value, context, block); const auto mul = BinaryOperator::CreateMul(cast, ConstantInt::get(cast->getType(), DatetimeScale), "mul", block); return mul; } template<> inline Value* GenFromScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { const auto div = BinaryOperator::CreateSDiv(value, ConstantInt::get(value->getType(), DatetimeScale), "div", block); const auto cast = StaticCast::TLayout>(div, context, block); return cast; } template<> inline Value* GenToScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { return StaticCast::TLayout, TScaledDate>(value, context, block); } template<> inline Value* GenFromScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { return StaticCast::TLayout>(value, context, block); } template<> inline Value* GenToScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { return StaticCast::TLayout, TScaledDate>(value, context, block); } template<> inline Value* GenFromScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { return StaticCast::TLayout>(value, context, block); } template<> inline Value* GenToScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { const auto cast = StaticCast::TLayout, TScaledDate>(value, context, block); const auto mul = BinaryOperator::CreateMul(cast, ConstantInt::get(cast->getType(), DateScale), "mul", block); return mul; } template<> inline Value* GenFromScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { const auto div = BinaryOperator::CreateSDiv(value, ConstantInt::get(value->getType(), DateScale), "div", block); const auto cast = StaticCast::TLayout>(div, context, block); return cast; } template<> inline Value* GenToScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { const auto cast = StaticCast::TLayout, TScaledDate>(value, context, block); const auto mul = BinaryOperator::CreateMul(cast, ConstantInt::get(cast->getType(), DatetimeScale), "mul", block); return mul; } template<> inline Value* GenFromScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { const auto div = BinaryOperator::CreateSDiv(value, ConstantInt::get(value->getType(), DatetimeScale), "div", block); const auto cast = StaticCast::TLayout>(div, context, block); return cast; } template<> inline Value* GenToScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { return StaticCast::TLayout, TScaledDate>(value, context, block); } template<> inline Value* GenFromScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { return StaticCast::TLayout>(value, context, block); } template<> inline Value* GenToScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { const auto cast = StaticCast::TLayout, TScaledDate>(value, context, block); const auto mul = BinaryOperator::CreateMul(cast, ConstantInt::get(cast->getType(), DateScale), "mul", block); return mul; } template<> inline Value* GenFromScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { const auto div = BinaryOperator::CreateSDiv(value, ConstantInt::get(value->getType(), DateScale), "div", block); const auto cast = StaticCast::TLayout>(div, context, block); return cast; } template<> inline Value* GenToScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { const auto cast = StaticCast::TLayout, TScaledDate>(value, context, block); const auto mul = BinaryOperator::CreateMul(cast, ConstantInt::get(cast->getType(), DatetimeScale), "mul", block); return mul; } template<> inline Value* GenFromScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { const auto div = BinaryOperator::CreateSDiv(value, ConstantInt::get(value->getType(), DatetimeScale), "div", block); const auto cast = StaticCast::TLayout>(div, context, block); return cast; } template<> inline Value* GenToScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { return StaticCast::TLayout, TScaledDate>(value, context, block); } template<> inline Value* GenFromScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { return StaticCast::TLayout>(value, context, block); } template<> inline Value* GenToScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { const auto cast = StaticCast::TLayout, TScaledDate>(value, context, block); const auto mul = BinaryOperator::CreateMul(cast, ConstantInt::get(cast->getType(), DateScale), "mul", block); return mul; } template<> inline Value* GenFromScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { const auto div = BinaryOperator::CreateSDiv(value, ConstantInt::get(value->getType(), DateScale), "div", block); const auto cast = StaticCast::TLayout>(div, context, block); return cast; } template<> inline Value* GenToScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { const auto cast = StaticCast::TLayout, TScaledDate>(value, context, block); const auto mul = BinaryOperator::CreateMul(cast, ConstantInt::get(cast->getType(), DatetimeScale), "mul", block); return mul; } template<> inline Value* GenFromScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { const auto div = BinaryOperator::CreateSDiv(value, ConstantInt::get(value->getType(), DatetimeScale), "div", block); const auto cast = StaticCast::TLayout>(div, context, block); return cast; } template<> inline Value* GenToScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { return StaticCast::TLayout, TScaledDate>(value, context, block); } template<> inline Value* GenFromScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { return StaticCast::TLayout>(value, context, block); } template<> inline Value* GenToScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { return StaticCast::TLayout, TScaledDate>(value, context, block); } template<> inline Value* GenFromScaledDate>(Value* value, LLVMContext &context, BasicBlock* block) { return StaticCast::TLayout>(value, context, block); } #endif } }