OmniSciDB  06b3bd477c
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CastIR.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017 MapD Technologies, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "CodeGenerator.h"
18 #include "Execute.h"
19 
20 llvm::Value* CodeGenerator::codegenCast(const Analyzer::UOper* uoper,
21  const CompilationOptions& co) {
22  CHECK_EQ(uoper->get_optype(), kCAST);
23  const auto& ti = uoper->get_type_info();
24  const auto operand = uoper->get_operand();
25  const auto operand_as_const = dynamic_cast<const Analyzer::Constant*>(operand);
26  // For dictionary encoded constants, the cast holds the dictionary id
27  // information as the compression parameter; handle this case separately.
28  llvm::Value* operand_lv{nullptr};
29  if (operand_as_const) {
30  const auto operand_lvs =
31  codegen(operand_as_const, ti.get_compression(), ti.get_comp_param(), co);
32  if (operand_lvs.size() == 3) {
33  operand_lv = cgen_state_->emitCall("string_pack", {operand_lvs[1], operand_lvs[2]});
34  } else {
35  operand_lv = operand_lvs.front();
36  }
37  } else {
38  operand_lv = codegen(operand, true, co).front();
39  }
40  const auto& operand_ti = operand->get_type_info();
41  return codegenCast(operand_lv, operand_ti, ti, operand_as_const, co);
42 }
43 
44 namespace {
45 
46 bool byte_array_cast(const SQLTypeInfo& operand_ti, const SQLTypeInfo& ti) {
47  return (operand_ti.is_array() && ti.is_array() && ti.get_subtype() == kTINYINT &&
48  operand_ti.get_size() > 0 && operand_ti.get_size() == ti.get_size());
49 }
50 
51 } // namespace
52 
53 llvm::Value* CodeGenerator::codegenCast(llvm::Value* operand_lv,
54  const SQLTypeInfo& operand_ti,
55  const SQLTypeInfo& ti,
56  const bool operand_is_const,
57  const CompilationOptions& co) {
58  if (byte_array_cast(operand_ti, ti)) {
59  auto* byte_array_type = get_int_array_type(8, ti.get_size(), cgen_state_->context_);
60  return cgen_state_->ir_builder_.CreatePointerCast(operand_lv,
61  byte_array_type->getPointerTo());
62  }
63  if (operand_lv->getType()->isIntegerTy()) {
64  if (operand_ti.is_string()) {
65  return codegenCastFromString(operand_lv, operand_ti, ti, operand_is_const, co);
66  }
67  CHECK(operand_ti.is_integer() || operand_ti.is_decimal() || operand_ti.is_time() ||
68  operand_ti.is_boolean());
69  if (operand_ti.is_boolean()) {
70  // cast boolean to int8
71  CHECK(operand_lv->getType()->isIntegerTy(1) ||
72  operand_lv->getType()->isIntegerTy(8));
73  if (operand_lv->getType()->isIntegerTy(1)) {
74  operand_lv = cgen_state_->castToTypeIn(operand_lv, 8);
75  }
76  if (ti.is_boolean()) {
77  return operand_lv;
78  }
79  }
80  if (operand_ti.is_integer() && operand_lv->getType()->isIntegerTy(8) &&
81  ti.is_boolean()) {
82  // cast int8 to boolean
83  return codegenCastBetweenIntTypes(operand_lv, operand_ti, ti);
84  }
85  if (operand_ti.get_type() == kTIMESTAMP && ti.get_type() == kDATE) {
86  // Maybe we should instead generate DatetruncExpr directly from RelAlgTranslator
87  // for this pattern. However, DatetruncExpr is supposed to return a timestamp,
88  // whereas this cast returns a date. The underlying type for both is still the same,
89  // but it still doesn't look like a good idea to misuse DatetruncExpr.
90  // Date will have default precision of day, but TIMESTAMP dimension would
91  // matter but while converting date through seconds
93  operand_lv, operand_ti.get_dimension(), !ti.get_notnull());
94  }
95  if ((operand_ti.get_type() == kTIMESTAMP || operand_ti.get_type() == kDATE) &&
96  ti.get_type() == kTIMESTAMP) {
97  const auto operand_dimen =
98  (operand_ti.is_timestamp()) ? operand_ti.get_dimension() : 0;
99  if (operand_dimen != ti.get_dimension()) {
101  operand_lv, operand_ti, ti, !ti.get_notnull());
102  }
103  }
104  if (ti.is_integer() || ti.is_decimal() || ti.is_time()) {
105  return codegenCastBetweenIntTypes(operand_lv, operand_ti, ti);
106  } else {
107  return codegenCastToFp(operand_lv, operand_ti, ti);
108  }
109  } else {
110  return codegenCastFromFp(operand_lv, operand_ti, ti);
111  }
112  CHECK(false);
113  return nullptr;
114 }
115 
116 llvm::Value* CodeGenerator::codegenCastTimestampToDate(llvm::Value* ts_lv,
117  const int dimen,
118  const bool nullable) {
119  CHECK(ts_lv->getType()->isIntegerTy(64));
120  std::vector<llvm::Value*> datetrunc_args{ts_lv};
121  if (dimen > 0) {
122  static const std::string hptodate_fname = "DateTruncateHighPrecisionToDate";
123  static const std::string hptodate_null_fname =
124  "DateTruncateHighPrecisionToDateNullable";
125  datetrunc_args.push_back(
127  if (nullable) {
128  datetrunc_args.push_back(cgen_state_->inlineIntNull(SQLTypeInfo(kBIGINT, false)));
129  }
130  return cgen_state_->emitExternalCall(nullable ? hptodate_null_fname : hptodate_fname,
132  datetrunc_args);
133  }
134  std::string datetrunc_fname{"DateTruncate"};
135  datetrunc_args.insert(datetrunc_args.begin(),
136  cgen_state_->llInt(static_cast<int32_t>(dtDAY)));
137  if (nullable) {
138  datetrunc_args.push_back(cgen_state_->inlineIntNull(SQLTypeInfo(kBIGINT, false)));
139  datetrunc_fname += "Nullable";
140  }
142  datetrunc_fname, get_int_type(64, cgen_state_->context_), datetrunc_args);
143 }
144 
145 llvm::Value* CodeGenerator::codegenCastBetweenTimestamps(llvm::Value* ts_lv,
146  const SQLTypeInfo& operand_ti,
147  const SQLTypeInfo& target_ti,
148  const bool nullable) {
149  const auto operand_dimen = operand_ti.get_dimension();
150  const auto target_dimen = target_ti.get_dimension();
151  if (operand_dimen == target_dimen) {
152  return ts_lv;
153  }
154  CHECK(ts_lv->getType()->isIntegerTy(64));
155  const auto scale =
156  DateTimeUtils::get_timestamp_precision_scale(abs(operand_dimen - target_dimen));
157  if (operand_dimen < target_dimen) {
158  codegenCastBetweenIntTypesOverflowChecks(ts_lv, operand_ti, target_ti, scale);
159  return nullable
160  ? cgen_state_->emitCall("mul_int64_t_nullable_lhs",
161  {ts_lv,
162  cgen_state_->llInt(static_cast<int64_t>(scale)),
163  cgen_state_->inlineIntNull(operand_ti)})
164  : cgen_state_->ir_builder_.CreateMul(
165  ts_lv, cgen_state_->llInt(static_cast<int64_t>(scale)));
166  }
167  return nullable
168  ? cgen_state_->emitCall("floor_div_nullable_lhs",
169  {ts_lv,
170  cgen_state_->llInt(static_cast<int64_t>(scale)),
171  cgen_state_->inlineIntNull(operand_ti)})
172  : cgen_state_->ir_builder_.CreateSDiv(
173  ts_lv, cgen_state_->llInt(static_cast<int64_t>(scale)));
174 }
175 
176 llvm::Value* CodeGenerator::codegenCastFromString(llvm::Value* operand_lv,
177  const SQLTypeInfo& operand_ti,
178  const SQLTypeInfo& ti,
179  const bool operand_is_const,
180  const CompilationOptions& co) {
181  if (!ti.is_string()) {
182  throw std::runtime_error("Cast from " + operand_ti.get_type_name() + " to " +
183  ti.get_type_name() + " not supported");
184  }
185  if (operand_ti.get_compression() == kENCODING_NONE &&
187  return operand_lv;
188  }
189  // dictionary encode non-constant
190  if (operand_ti.get_compression() != kENCODING_DICT && !operand_is_const) {
191  if (g_cluster) {
192  throw std::runtime_error(
193  "Cast from none-encoded string to dictionary-encoded not supported for "
194  "distributed queries");
195  }
196  if (g_enable_watchdog) {
197  throw WatchdogException(
198  "Cast from none-encoded string to dictionary-encoded would be slow");
199  }
200  CHECK_EQ(kENCODING_NONE, operand_ti.get_compression());
202  CHECK(operand_lv->getType()->isIntegerTy(64));
204  throw QueryMustRunOnCpu();
205  }
207  "string_compress",
209  {operand_lv,
210  cgen_state_->llInt(int64_t(executor()->getStringDictionaryProxy(
211  ti.get_comp_param(), executor()->getRowSetMemoryOwner(), true)))});
212  }
213  CHECK(operand_lv->getType()->isIntegerTy(32));
214  if (ti.get_compression() == kENCODING_NONE) {
215  if (g_cluster) {
216  throw std::runtime_error(
217  "Cast from dictionary-encoded string to none-encoded not supported for "
218  "distributed queries");
219  }
220  if (g_enable_watchdog) {
221  throw WatchdogException(
222  "Cast from dictionary-encoded string to none-encoded would be slow");
223  }
224  CHECK_EQ(kENCODING_DICT, operand_ti.get_compression());
226  throw QueryMustRunOnCpu();
227  }
228  const int64_t string_dictionary_ptr =
229  operand_ti.get_comp_param() == 0
230  ? reinterpret_cast<int64_t>(
231  executor()->getRowSetMemoryOwner()->getLiteralStringDictProxy())
232  : reinterpret_cast<int64_t>(executor()->getStringDictionaryProxy(
233  operand_ti.get_comp_param(), executor()->getRowSetMemoryOwner(), true));
235  "string_decompress",
237  {operand_lv, cgen_state_->llInt(string_dictionary_ptr)});
238  }
239  CHECK(operand_is_const);
240  CHECK_EQ(kENCODING_DICT, ti.get_compression());
241  return operand_lv;
242 }
243 
244 llvm::Value* CodeGenerator::codegenCastBetweenIntTypes(llvm::Value* operand_lv,
245  const SQLTypeInfo& operand_ti,
246  const SQLTypeInfo& ti,
247  bool upscale) {
248  if (ti.is_decimal() &&
249  (!operand_ti.is_decimal() || operand_ti.get_scale() <= ti.get_scale())) {
250  if (upscale) {
251  if (operand_ti.get_scale() < ti.get_scale()) { // scale only if needed
252  auto scale = exp_to_scale(ti.get_scale() - operand_ti.get_scale());
253  const auto scale_lv =
254  llvm::ConstantInt::get(get_int_type(64, cgen_state_->context_), scale);
255  operand_lv = cgen_state_->ir_builder_.CreateSExt(
256  operand_lv, get_int_type(64, cgen_state_->context_));
257 
258  codegenCastBetweenIntTypesOverflowChecks(operand_lv, operand_ti, ti, scale);
259 
260  if (operand_ti.get_notnull()) {
261  operand_lv = cgen_state_->ir_builder_.CreateMul(operand_lv, scale_lv);
262  } else {
263  operand_lv = cgen_state_->emitCall(
264  "scale_decimal_up",
265  {operand_lv,
266  scale_lv,
267  cgen_state_->llInt(inline_int_null_val(operand_ti)),
269  }
270  }
271  }
272  } else if (operand_ti.is_decimal()) {
273  // rounded scale down
274  auto scale = (int64_t)exp_to_scale(operand_ti.get_scale() - ti.get_scale());
275  const auto scale_lv =
276  llvm::ConstantInt::get(get_int_type(64, cgen_state_->context_), scale);
277 
278  const auto operand_width =
279  static_cast<llvm::IntegerType*>(operand_lv->getType())->getBitWidth();
280 
281  std::string method_name = "scale_decimal_down_nullable";
282  if (operand_ti.get_notnull()) {
283  method_name = "scale_decimal_down_not_nullable";
284  }
285 
286  CHECK(operand_width == 64);
287  operand_lv = cgen_state_->emitCall(
288  method_name,
289  {operand_lv, scale_lv, cgen_state_->llInt(inline_int_null_val(operand_ti))});
290  }
291  if (ti.is_integer() && operand_ti.is_integer() &&
292  operand_ti.get_logical_size() > ti.get_logical_size()) {
293  codegenCastBetweenIntTypesOverflowChecks(operand_lv, operand_ti, ti, 1);
294  }
295 
296  const auto operand_width =
297  static_cast<llvm::IntegerType*>(operand_lv->getType())->getBitWidth();
298  const auto target_width = get_bit_width(ti);
299  if (target_width == operand_width) {
300  return operand_lv;
301  }
302  if (operand_ti.get_notnull()) {
303  return cgen_state_->ir_builder_.CreateCast(
304  target_width > operand_width ? llvm::Instruction::CastOps::SExt
305  : llvm::Instruction::CastOps::Trunc,
306  operand_lv,
307  get_int_type(target_width, cgen_state_->context_));
308  }
309  return cgen_state_->emitCall("cast_" + numeric_type_name(operand_ti) + "_to_" +
310  numeric_type_name(ti) + "_nullable",
311  {operand_lv,
312  cgen_state_->inlineIntNull(operand_ti),
313  cgen_state_->inlineIntNull(ti)});
314 }
315 
317  llvm::Value* operand_lv,
318  const SQLTypeInfo& operand_ti,
319  const SQLTypeInfo& ti,
320  const int64_t scale) {
321  llvm::Value* chosen_max{nullptr};
322  llvm::Value* chosen_min{nullptr};
323  std::tie(chosen_max, chosen_min) =
325 
327  auto cast_ok =
328  llvm::BasicBlock::Create(cgen_state_->context_, "cast_ok", cgen_state_->row_func_);
329  auto cast_fail = llvm::BasicBlock::Create(
330  cgen_state_->context_, "cast_fail", cgen_state_->row_func_);
331  auto operand_max = static_cast<llvm::ConstantInt*>(chosen_max)->getSExtValue() / scale;
332  auto operand_min = static_cast<llvm::ConstantInt*>(chosen_min)->getSExtValue() / scale;
333  const auto ti_llvm_type =
335  llvm::Value* operand_max_lv = llvm::ConstantInt::get(ti_llvm_type, operand_max);
336  llvm::Value* operand_min_lv = llvm::ConstantInt::get(ti_llvm_type, operand_min);
337  const bool is_narrowing = operand_ti.get_logical_size() > ti.get_logical_size();
338  if (is_narrowing) {
339  const auto operand_ti_llvm_type =
341  operand_max_lv =
342  cgen_state_->ir_builder_.CreateSExt(operand_max_lv, operand_ti_llvm_type);
343  operand_min_lv =
344  cgen_state_->ir_builder_.CreateSExt(operand_min_lv, operand_ti_llvm_type);
345  }
346  llvm::Value* over{nullptr};
347  llvm::Value* under{nullptr};
348  if (operand_ti.get_notnull()) {
349  over = cgen_state_->ir_builder_.CreateICmpSGT(operand_lv, operand_max_lv);
350  under = cgen_state_->ir_builder_.CreateICmpSLE(operand_lv, operand_min_lv);
351  } else {
352  const auto type_name =
353  is_narrowing ? numeric_type_name(operand_ti) : numeric_type_name(ti);
354  const auto null_operand_val = cgen_state_->llInt(inline_int_null_val(operand_ti));
355  const auto null_bool_val = cgen_state_->inlineIntNull(SQLTypeInfo(kBOOLEAN, false));
356  over = toBool(cgen_state_->emitCall(
357  "gt_" + type_name + "_nullable_lhs",
358  {operand_lv, operand_max_lv, null_operand_val, null_bool_val}));
359  under = toBool(cgen_state_->emitCall(
360  "le_" + type_name + "_nullable_lhs",
361  {operand_lv, operand_min_lv, null_operand_val, null_bool_val}));
362  }
363  const auto detected = cgen_state_->ir_builder_.CreateOr(over, under, "overflow");
364  cgen_state_->ir_builder_.CreateCondBr(detected, cast_fail, cast_ok);
365 
366  cgen_state_->ir_builder_.SetInsertPoint(cast_fail);
367  cgen_state_->ir_builder_.CreateRet(
368  cgen_state_->llInt(Executor::ERR_OVERFLOW_OR_UNDERFLOW));
369 
370  cgen_state_->ir_builder_.SetInsertPoint(cast_ok);
371 }
372 
373 llvm::Value* CodeGenerator::codegenCastToFp(llvm::Value* operand_lv,
374  const SQLTypeInfo& operand_ti,
375  const SQLTypeInfo& ti) {
376  if (!ti.is_fp()) {
377  throw std::runtime_error("Cast from " + operand_ti.get_type_name() + " to " +
378  ti.get_type_name() + " not supported");
379  }
380  const auto to_tname = numeric_type_name(ti);
381  llvm::Value* result_lv{nullptr};
382  if (operand_ti.get_notnull()) {
383  result_lv = cgen_state_->ir_builder_.CreateSIToFP(
384  operand_lv,
385  ti.get_type() == kFLOAT ? llvm::Type::getFloatTy(cgen_state_->context_)
386  : llvm::Type::getDoubleTy(cgen_state_->context_));
387  } else {
388  result_lv = cgen_state_->emitCall(
389  "cast_" + numeric_type_name(operand_ti) + "_to_" + to_tname + "_nullable",
390  {operand_lv,
391  cgen_state_->inlineIntNull(operand_ti),
392  cgen_state_->inlineFpNull(ti)});
393  }
394  CHECK(result_lv);
395  if (operand_ti.get_scale()) {
396  result_lv = cgen_state_->ir_builder_.CreateFDiv(
397  result_lv,
398  llvm::ConstantFP::get(result_lv->getType(),
399  exp_to_scale(operand_ti.get_scale())));
400  }
401  return result_lv;
402 }
403 
404 llvm::Value* CodeGenerator::codegenCastFromFp(llvm::Value* operand_lv,
405  const SQLTypeInfo& operand_ti,
406  const SQLTypeInfo& ti) {
407  if (!operand_ti.is_fp() || !ti.is_number() || ti.is_decimal()) {
408  throw std::runtime_error("Cast from " + operand_ti.get_type_name() + " to " +
409  ti.get_type_name() + " not supported");
410  }
411  if (operand_ti.get_type() == ti.get_type()) {
412  // Should not have been called when both dimensions are same.
413  return operand_lv;
414  }
415  CHECK(operand_lv->getType()->isFloatTy() || operand_lv->getType()->isDoubleTy());
416  if (operand_ti.get_notnull()) {
417  if (ti.get_type() == kDOUBLE) {
418  return cgen_state_->ir_builder_.CreateFPExt(
419  operand_lv, llvm::Type::getDoubleTy(cgen_state_->context_));
420  } else if (ti.get_type() == kFLOAT) {
421  return cgen_state_->ir_builder_.CreateFPTrunc(
422  operand_lv, llvm::Type::getFloatTy(cgen_state_->context_));
423  } else if (ti.is_integer()) {
424  return cgen_state_->ir_builder_.CreateFPToSI(
425  operand_lv, get_int_type(get_bit_width(ti), cgen_state_->context_));
426  } else {
427  CHECK(false);
428  }
429  } else {
430  const auto from_tname = numeric_type_name(operand_ti);
431  const auto to_tname = numeric_type_name(ti);
432  if (ti.is_fp()) {
433  return cgen_state_->emitCall("cast_" + from_tname + "_to_" + to_tname + "_nullable",
434  {operand_lv,
435  cgen_state_->inlineFpNull(operand_ti),
436  cgen_state_->inlineFpNull(ti)});
437  } else if (ti.is_integer()) {
438  return cgen_state_->emitCall("cast_" + from_tname + "_to_" + to_tname + "_nullable",
439  {operand_lv,
440  cgen_state_->inlineFpNull(operand_ti),
441  cgen_state_->inlineIntNull(ti)});
442  } else {
443  CHECK(false);
444  }
445  }
446  CHECK(false);
447  return nullptr;
448 }
HOST DEVICE SQLTypes get_subtype() const
Definition: sqltypes.h:259
#define CHECK_EQ(x, y)
Definition: Logger.h:205
llvm::Value * castToTypeIn(llvm::Value *val, const size_t bit_width)
Definition: CgenState.cpp:106
llvm::Value * codegenCastFromFp(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
Definition: CastIR.cpp:404
HOST DEVICE int get_size() const
Definition: sqltypes.h:268
bool g_enable_watchdog
bool is_timestamp() const
Definition: sqltypes.h:652
CgenState * cgen_state_
bool is_fp() const
Definition: sqltypes.h:419
HOST DEVICE int get_scale() const
Definition: sqltypes.h:263
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)
Definition: CgenState.h:206
llvm::IRBuilder ir_builder_
Definition: CgenState.h:319
llvm::Value * codegenCastToFp(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
Definition: CastIR.cpp:373
Definition: sqldefs.h:49
bool byte_array_cast(const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
Definition: CastIR.cpp:46
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:258
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
bool is_number() const
Definition: sqltypes.h:420
bool is_time() const
Definition: sqltypes.h:421
llvm::Function * row_func_
Definition: CgenState.h:315
size_t get_bit_width(const SQLTypeInfo &ti)
llvm::LLVMContext & context_
Definition: CgenState.h:317
CHECK(cgen_state)
int get_logical_size() const
Definition: sqltypes.h:269
bool is_integer() const
Definition: sqltypes.h:417
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
static const int32_t ERR_OVERFLOW_OR_UNDERFLOW
Definition: Execute.h:941
llvm::Value * codegenCastBetweenIntTypes(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, bool upscale=true)
Definition: CastIR.cpp:244
bool needs_error_check_
Definition: CgenState.h:334
bool is_boolean() const
Definition: sqltypes.h:422
llvm::Value * codegenCastTimestampToDate(llvm::Value *ts_lv, const int dimen, const bool nullable)
Definition: CastIR.cpp:116
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:79
llvm::Value * emitCall(const std::string &fname, const std::vector< llvm::Value * > &args)
Definition: CgenState.cpp:137
ExecutorDeviceType device_type
std::vector< llvm::Value * > codegen(const Analyzer::Expr *, const bool fetch_columns, const CompilationOptions &)
Definition: IRCodegen.cpp:26
Definition: sqltypes.h:54
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:266
const Expr * get_operand() const
Definition: Analyzer.h:372
void codegenCastBetweenIntTypesOverflowChecks(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, const int64_t scale)
Definition: CastIR.cpp:316
HOST DEVICE int get_dimension() const
Definition: sqltypes.h:260
std::string get_type_name() const
Definition: sqltypes.h:361
llvm::Value * toBool(llvm::Value *)
Definition: LogicalIR.cpp:333
HOST DEVICE int get_comp_param() const
Definition: sqltypes.h:267
llvm::Value * codegenCastBetweenTimestamps(llvm::Value *ts_lv, const SQLTypeInfo &operand_dimen, const SQLTypeInfo &target_dimen, const bool nullable)
Definition: CastIR.cpp:145
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:296
constexpr int64_t get_timestamp_precision_scale(const int32_t dimen)
Definition: DateTimeUtils.h:51
uint64_t exp_to_scale(const unsigned exp)
int64_t inline_int_null_val(const SQL_TYPE_INFO &ti)
bool g_cluster
llvm::Value * codegenCastFromString(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, const bool operand_is_const, const CompilationOptions &co)
Definition: CastIR.cpp:176
llvm::Value * codegenCast(const Analyzer::UOper *, const CompilationOptions &)
Definition: CastIR.cpp:20
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:138
bool is_string() const
Definition: sqltypes.h:415
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:265
llvm::ArrayType * get_int_array_type(int const width, int count, llvm::LLVMContext &context)
bool is_decimal() const
Definition: sqltypes.h:418
std::pair< llvm::ConstantInt *, llvm::ConstantInt * > inlineIntMaxMin(const size_t byte_width, const bool is_signed)
Definition: CgenState.cpp:77
SQLOps get_optype() const
Definition: Analyzer.h:371
bool is_array() const
Definition: sqltypes.h:423
llvm::ConstantFP * inlineFpNull(const SQLTypeInfo &)
Definition: CgenState.cpp:65
Executor * executor() const