30 llvm::Value* operand_lv{
nullptr};
31 if (operand_as_const) {
32 const auto operand_lvs =
33 codegen(operand_as_const, ti.get_compression(), ti.getStringDictKey(), co);
34 if (operand_lvs.size() == 3) {
37 operand_lv = operand_lvs.front();
40 operand_lv =
codegen(operand,
true, co).front();
46 if (operand_lv->getType()->isPointerTy() &&
47 operand_lv->getType()->getPointerElementType()->isStructTy()) {
49 operand_lv->getType()->getPointerElementType(), operand_lv);
55 "register_buffer_with_executor_rsm",
56 llvm::Type::getVoidTy(
executor_->cgen_state_->context_),
58 operand_lv = cgen_state_->emitCall(
"string_pack", {ptr, len});
60 const auto& operand_ti = operand->get_type_info();
61 return codegenCast(operand_lv, operand_ti, ti, operand_as_const, co);
76 const bool operand_is_const,
82 byte_array_type->getPointerTo());
87 }
else if (operand_lv->getType()->isIntegerTy()) {
93 CHECK(operand_lv->getType()->isIntegerTy(1) ||
94 operand_lv->getType()->isIntegerTy(8));
95 if (operand_lv->getType()->isIntegerTy(1)) {
102 if (operand_ti.
is_integer() && operand_lv->getType()->isIntegerTy(8) &&
123 const auto operand_dimen =
144 const bool nullable) {
145 std::vector<llvm::Value*> datetrunc_args{ts_lv};
146 std::string hptodate_fname;
148 hptodate_fname =
"ExtractTimeFromHPTimestamp";
149 datetrunc_args.push_back(
152 hptodate_fname =
"ExtractTimeFromLPTimestamp";
156 hptodate_fname +=
"Nullable";
164 const bool nullable) {
166 CHECK(ts_lv->getType()->isIntegerTy(64));
170 "DateTruncateHighPrecisionToDateNullable",
176 return cgen_state_->emitExternalCall(
177 "DateTruncateHighPrecisionToDate",
182 std::unique_ptr<CodeGenerator::NullCheckCodegen> nullcheck_codegen;
185 std::make_unique<NullCheckCodegen>(cgen_state_,
189 "cast_timestamp_nullcheck");
191 auto ret = cgen_state_->emitExternalCall(
192 "datetrunc_day",
get_int_type(64, cgen_state_->context_), {ts_lv});
193 if (nullcheck_codegen) {
194 ret = nullcheck_codegen->finalize(
ll_int(
NULL_BIGINT, cgen_state_->context_), ret);
202 const bool nullable) {
206 if (operand_dimen == target_dimen) {
209 CHECK(ts_lv->getType()->isIntegerTy(64));
212 if (operand_dimen < target_dimen) {
234 const bool operand_is_const,
238 throw std::runtime_error(
"Cast from " + operand_ti.
get_type_name() +
" to " +
255 const int64_t source_string_proxy_handle =
256 reinterpret_cast<int64_t
>(
executor()->getStringDictionaryProxy(
259 const int64_t dest_string_proxy_handle =
260 reinterpret_cast<int64_t
>(
executor()->getStringDictionaryProxy(
263 auto source_string_proxy_handle_lv =
cgen_state_->
llInt(source_string_proxy_handle);
264 auto dest_string_proxy_handle_lv =
cgen_state_->
llInt(dest_string_proxy_handle);
266 std::vector<llvm::Value*> string_cast_lvs{
267 operand_lv, source_string_proxy_handle_lv, dest_string_proxy_handle_lv};
270 "intersect_translate_string_id_to_other_dict",
280 const std::vector<StringOps_Namespace::StringOpInfo> string_op_infos;
281 auto string_dictionary_translation_mgr =
282 std::make_unique<StringDictionaryTranslationMgr>(
297 ->
codegen(operand_lv, operand_ti,
true , co);
302 throw std::runtime_error(
303 "Cast from none-encoded string to dictionary-encoded not supported for "
304 "distributed queries");
308 CHECK(operand_lv->getType()->isStructTy());
319 CHECK(operand_lv->getType()->isIntegerTy(32));
322 throw std::runtime_error(
323 "Cast from dictionary-encoded string to none-encoded not "
324 "currently supported for distributed queries.");
332 const int64_t string_dictionary_ptr =
334 ?
reinterpret_cast<int64_t
>(
335 executor()->getRowSetMemoryOwner()->getLiteralStringDictProxy())
336 : reinterpret_cast<int64_t>(
345 CHECK(operand_is_const);
353 const bool operand_is_const,
358 throw std::runtime_error(
"Cast to none-encoded strings currently unsupported.");
361 throw std::runtime_error(
362 "Cast to dictionary-encoded string type not supported for "
363 "distributed queries");
368 std::string fn_call{
"convert_to_string_and_encode_"};
369 const auto operand_type = operand_ti.
get_type();
370 std::vector operand_lvs{operand_lv};
371 switch (operand_type) {
385 fn_call +=
"decimal";
386 operand_lvs.emplace_back(llvm::ConstantInt::get(
388 operand_lvs.emplace_back(llvm::ConstantInt::get(
395 fn_call +=
"timestamp";
396 operand_lvs.emplace_back(llvm::ConstantInt::get(
403 throw std::runtime_error(
"Unimplemented type for string cast");
405 operand_lvs.emplace_back(
412 std::unique_ptr<CodeGenerator::NullCheckCodegen> nullcheck_codegen;
413 const bool is_nullable = !operand_ti.
get_notnull();
420 "cast_non_string_to_string_nullcheck");
421 CHECK(nullcheck_codegen);
422 ret = nullcheck_codegen->finalize(cgen_state_->inlineNull(ti), ret);
437 const auto scale_lv =
459 const auto scale_lv =
462 const auto operand_width =
463 static_cast<llvm::IntegerType*
>(operand_lv->getType())->getBitWidth();
465 std::string method_name =
"scale_decimal_down_nullable";
467 method_name =
"scale_decimal_down_not_nullable";
470 CHECK(operand_width == 64);
480 const auto operand_width =
481 static_cast<llvm::IntegerType*
>(operand_lv->getType())->getBitWidth();
483 if (target_width == operand_width) {
488 target_width > operand_width ? llvm::Instruction::CastOps::SExt
489 : llvm::Instruction::CastOps::Trunc,
501 llvm::Value* operand_lv,
504 const int64_t scale) {
506 llvm::Value* chosen_max{
nullptr};
507 llvm::Value* chosen_min{
nullptr};
508 std::tie(chosen_max, chosen_min) =
512 auto cast_ok = llvm::BasicBlock::Create(
514 auto cast_fail = llvm::BasicBlock::Create(
516 auto operand_max =
static_cast<llvm::ConstantInt*
>(chosen_max)->getSExtValue() / scale;
517 auto operand_min =
static_cast<llvm::ConstantInt*
>(chosen_min)->getSExtValue() / scale;
518 const auto ti_llvm_type =
520 llvm::Value* operand_max_lv = llvm::ConstantInt::get(ti_llvm_type, operand_max);
521 llvm::Value* operand_min_lv = llvm::ConstantInt::get(ti_llvm_type, operand_min);
524 const auto operand_ti_llvm_type =
531 llvm::Value* over{
nullptr};
532 llvm::Value* under{
nullptr};
543 {operand_lv, operand_max_lv, null_operand_val, null_bool_val}));
546 {operand_lv, operand_min_lv, null_operand_val, null_bool_val}));
548 const auto detected = cgen_state_->ir_builder_.CreateOr(over, under,
"overflow");
549 cgen_state_->ir_builder_.CreateCondBr(detected, cast_fail, cast_ok);
551 cgen_state_->ir_builder_.SetInsertPoint(cast_fail);
552 cgen_state_->ir_builder_.CreateRet(
553 cgen_state_->llInt(int32_t(heavyai::ErrorCode::OVERFLOW_OR_UNDERFLOW)));
555 cgen_state_->ir_builder_.SetInsertPoint(cast_ok);
563 throw std::runtime_error(
"Cast from " + operand_ti.
get_type_name() +
" to " +
566 llvm::Value* result_lv;
572 if (
auto const scale = static_cast<unsigned>(operand_ti.
get_scale())) {
575 result_lv, llvm::ConstantFP::get(result_lv->getType(), divider));
578 if (
auto const scale = static_cast<unsigned>(operand_ti.
get_scale())) {
588 llvm::ConstantFP::get(fp_type, divider)});
606 throw std::runtime_error(
"Cast from " + operand_ti.
get_type_name() +
" to " +
613 CHECK(operand_lv->getType()->isFloatTy() || operand_lv->getType()->isDoubleTy());
623 auto* fp_type = operand_lv->getType()->isFloatTy()
626 auto* zero = llvm::ConstantFP::get(fp_type, 0.0);
627 auto* mhalf = llvm::ConstantFP::get(fp_type, -0.5);
628 auto* phalf = llvm::ConstantFP::get(fp_type, 0.5);
HOST DEVICE SQLTypes get_subtype() const
double power10(unsigned const x)
llvm::Value * castToTypeIn(llvm::Value *val, const size_t bit_width)
llvm::Value * codegenCastFromFp(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
HOST DEVICE int get_size() const
bool is_timestamp() const
llvm::Value * codegenCastNonStringToString(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, const bool operand_is_const, const CompilationOptions &co)
HOST DEVICE int get_scale() const
llvm::ConstantInt * ll_int(const T v, llvm::LLVMContext &context)
llvm::IRBuilder ir_builder_
llvm::Value * codegenCastToFp(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
bool byte_array_cast(const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
HOST DEVICE SQLTypes get_type() const
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
size_t get_bit_width(const SQLTypeInfo &ti)
llvm::LLVMContext & context_
llvm::Function * current_func_
llvm::Value * emitExternalCall(const std::string &fname, llvm::Type *ret_type, const std::vector< llvm::Value * > args, const std::vector< llvm::Attribute::AttrKind > &fnattrs={}, const bool has_struct_return=false)
int get_logical_size() const
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
bool is_text_encoding_dict() const
llvm::Value * codegenCastBetweenIntTypes(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, bool upscale=true)
bool is_dict_intersection() const
llvm::Value * codegenCastTimestampToDate(llvm::Value *ts_lv, const int dimen, const bool nullable)
std::string toString(const Executor::ExtModuleKinds &kind)
const SQLTypeInfo & get_type_info() const
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
int get_precision() const
ExecutorDeviceType device_type
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
HOST DEVICE EncodingType get_compression() const
const Expr * get_operand() const
void codegenCastBetweenIntTypesOverflowChecks(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, const int64_t scale)
llvm::StructType * createStringViewStructType()
HOST DEVICE int get_dimension() const
std::string get_type_name() const
llvm::Value * toBool(llvm::Value *)
llvm::Value * codegenCastBetweenTimestamps(llvm::Value *ts_lv, const SQLTypeInfo &operand_dimen, const SQLTypeInfo &target_dimen, const bool nullable)
llvm::ConstantInt * llInt(const T v) const
constexpr int64_t get_timestamp_precision_scale(const int32_t dimen)
uint64_t exp_to_scale(const unsigned exp)
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
llvm::Value * codegenCastTimestampToTime(llvm::Value *ts_lv, const int dimen, const bool nullable)
llvm::Value * codegenCastFromString(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, const bool operand_is_const, const CompilationOptions &co)
const StringDictionaryTranslationMgr * moveStringDictionaryTranslationMgr(std::unique_ptr< const StringDictionaryTranslationMgr > &&str_dict_translation_mgr)
llvm::Value * codegenCast(const Analyzer::UOper *, const CompilationOptions &)
std::string numeric_type_name(const SQLTypeInfo &ti)
HOST DEVICE bool get_notnull() const
llvm::Value * codegen(llvm::Value *str_id_input, const SQLTypeInfo &input_ti, const bool add_nullcheck, const CompilationOptions &co) const
constexpr auto type_name() noexcept
llvm::ArrayType * get_int_array_type(int const width, int count, llvm::LLVMContext &context)
std::pair< llvm::ConstantInt *, llvm::ConstantInt * > inlineIntMaxMin(const size_t byte_width, const bool is_signed)
SQLOps get_optype() const
static constexpr int32_t literalsDictId
const shared::StringDictKey & getStringDictKey() const
llvm::ConstantFP * inlineFpNull(const SQLTypeInfo &)
Executor * executor() const