OmniSciDB  467d548b97
 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) {
23  CHECK_EQ(uoper->get_optype(), kCAST);
24  const auto& ti = uoper->get_type_info();
25  const auto operand = uoper->get_operand();
26  const auto operand_as_const = dynamic_cast<const Analyzer::Constant*>(operand);
27  // For dictionary encoded constants, the cast holds the dictionary id
28  // information as the compression parameter; handle this case separately.
29  llvm::Value* operand_lv{nullptr};
30  if (operand_as_const) {
31  const auto operand_lvs =
32  codegen(operand_as_const, ti.get_compression(), ti.get_comp_param(), co);
33  if (operand_lvs.size() == 3) {
34  operand_lv = cgen_state_->emitCall("string_pack", {operand_lvs[1], operand_lvs[2]});
35  } else {
36  operand_lv = operand_lvs.front();
37  }
38  } else {
39  operand_lv = codegen(operand, true, co).front();
40  }
41  const auto& operand_ti = operand->get_type_info();
42  return codegenCast(operand_lv, operand_ti, ti, operand_as_const, co);
43 }
44 
45 namespace {
46 
47 bool byte_array_cast(const SQLTypeInfo& operand_ti, const SQLTypeInfo& ti) {
48  return (operand_ti.is_array() && ti.is_array() && ti.get_subtype() == kTINYINT &&
49  operand_ti.get_size() > 0 && operand_ti.get_size() == ti.get_size());
50 }
51 
52 } // namespace
53 
54 llvm::Value* CodeGenerator::codegenCast(llvm::Value* operand_lv,
55  const SQLTypeInfo& operand_ti,
56  const SQLTypeInfo& ti,
57  const bool operand_is_const,
58  const CompilationOptions& co) {
60  if (byte_array_cast(operand_ti, ti)) {
61  auto* byte_array_type = get_int_array_type(8, ti.get_size(), cgen_state_->context_);
62  return cgen_state_->ir_builder_.CreatePointerCast(operand_lv,
63  byte_array_type->getPointerTo());
64  }
65  if (operand_lv->getType()->isIntegerTy()) {
66  if (operand_ti.is_string()) {
67  return codegenCastFromString(operand_lv, operand_ti, ti, operand_is_const, co);
68  }
69  CHECK(operand_ti.is_integer() || operand_ti.is_decimal() || operand_ti.is_time() ||
70  operand_ti.is_boolean());
71  if (operand_ti.is_boolean()) {
72  // cast boolean to int8
73  CHECK(operand_lv->getType()->isIntegerTy(1) ||
74  operand_lv->getType()->isIntegerTy(8));
75  if (operand_lv->getType()->isIntegerTy(1)) {
76  operand_lv = cgen_state_->castToTypeIn(operand_lv, 8);
77  }
78  if (ti.is_boolean()) {
79  return operand_lv;
80  }
81  }
82  if (operand_ti.is_integer() && operand_lv->getType()->isIntegerTy(8) &&
83  ti.is_boolean()) {
84  // cast int8 to boolean
85  return codegenCastBetweenIntTypes(operand_lv, operand_ti, ti);
86  }
87  if (operand_ti.get_type() == kTIMESTAMP && ti.get_type() == kDATE) {
88  // Maybe we should instead generate DatetruncExpr directly from RelAlgTranslator
89  // for this pattern. However, DatetruncExpr is supposed to return a timestamp,
90  // whereas this cast returns a date. The underlying type for both is still the same,
91  // but it still doesn't look like a good idea to misuse DatetruncExpr.
92  // Date will have default precision of day, but TIMESTAMP dimension would
93  // matter but while converting date through seconds
95  operand_lv, operand_ti.get_dimension(), !ti.get_notnull());
96  }
97  if ((operand_ti.get_type() == kTIMESTAMP || operand_ti.get_type() == kDATE) &&
98  ti.get_type() == kTIMESTAMP) {
99  const auto operand_dimen =
100  (operand_ti.is_timestamp()) ? operand_ti.get_dimension() : 0;
101  if (operand_dimen != ti.get_dimension()) {
103  operand_lv, operand_ti, ti, !ti.get_notnull());
104  }
105  }
106  if (ti.is_integer() || ti.is_decimal() || ti.is_time()) {
107  return codegenCastBetweenIntTypes(operand_lv, operand_ti, ti);
108  } else {
109  return codegenCastToFp(operand_lv, operand_ti, ti);
110  }
111  } else {
112  return codegenCastFromFp(operand_lv, operand_ti, ti);
113  }
114  CHECK(false);
115  return nullptr;
116 }
117 
118 llvm::Value* CodeGenerator::codegenCastTimestampToDate(llvm::Value* ts_lv,
119  const int dimen,
120  const bool nullable) {
122  CHECK(ts_lv->getType()->isIntegerTy(64));
123  if (dimen > 0) {
124  if (nullable) {
126  "DateTruncateHighPrecisionToDateNullable",
128  {{ts_lv,
131  }
132  return cgen_state_->emitExternalCall(
133  "DateTruncateHighPrecisionToDate",
134  get_int_type(64, cgen_state_->context_),
135  {{ts_lv,
136  cgen_state_->llInt(DateTimeUtils::get_timestamp_precision_scale(dimen))}});
137  }
138  std::unique_ptr<CodeGenerator::NullCheckCodegen> nullcheck_codegen;
139  if (nullable) {
140  nullcheck_codegen =
141  std::make_unique<NullCheckCodegen>(cgen_state_,
142  executor(),
143  ts_lv,
144  SQLTypeInfo(kTIMESTAMP, dimen, 0, !nullable),
145  "cast_timestamp_nullcheck");
146  }
147  auto ret = cgen_state_->emitExternalCall(
148  "datetrunc_day", get_int_type(64, cgen_state_->context_), {ts_lv});
149  if (nullcheck_codegen) {
150  ret = nullcheck_codegen->finalize(ll_int(NULL_BIGINT, cgen_state_->context_), ret);
151  }
152  return ret;
153 }
154 
155 llvm::Value* CodeGenerator::codegenCastBetweenTimestamps(llvm::Value* ts_lv,
156  const SQLTypeInfo& operand_ti,
157  const SQLTypeInfo& target_ti,
158  const bool nullable) {
160  const auto operand_dimen = operand_ti.get_dimension();
161  const auto target_dimen = target_ti.get_dimension();
162  if (operand_dimen == target_dimen) {
163  return ts_lv;
164  }
165  CHECK(ts_lv->getType()->isIntegerTy(64));
166  const auto scale =
167  DateTimeUtils::get_timestamp_precision_scale(abs(operand_dimen - target_dimen));
168  if (operand_dimen < target_dimen) {
169  codegenCastBetweenIntTypesOverflowChecks(ts_lv, operand_ti, target_ti, scale);
170  return nullable
171  ? cgen_state_->emitCall("mul_int64_t_nullable_lhs",
172  {ts_lv,
173  cgen_state_->llInt(static_cast<int64_t>(scale)),
174  cgen_state_->inlineIntNull(operand_ti)})
175  : cgen_state_->ir_builder_.CreateMul(
176  ts_lv, cgen_state_->llInt(static_cast<int64_t>(scale)));
177  }
178  return nullable
179  ? cgen_state_->emitCall("floor_div_nullable_lhs",
180  {ts_lv,
181  cgen_state_->llInt(static_cast<int64_t>(scale)),
182  cgen_state_->inlineIntNull(operand_ti)})
183  : cgen_state_->ir_builder_.CreateSDiv(
184  ts_lv, cgen_state_->llInt(static_cast<int64_t>(scale)));
185 }
186 
187 llvm::Value* CodeGenerator::codegenCastFromString(llvm::Value* operand_lv,
188  const SQLTypeInfo& operand_ti,
189  const SQLTypeInfo& ti,
190  const bool operand_is_const,
191  const CompilationOptions& co) {
193  if (!ti.is_string()) {
194  throw std::runtime_error("Cast from " + operand_ti.get_type_name() + " to " +
195  ti.get_type_name() + " not supported");
196  }
197  if (operand_ti.get_compression() == kENCODING_NONE &&
199  return operand_lv;
200  }
201  // dictionary encode non-constant
202  if (operand_ti.get_compression() != kENCODING_DICT && !operand_is_const) {
203  if (g_cluster) {
204  throw std::runtime_error(
205  "Cast from none-encoded string to dictionary-encoded not supported for "
206  "distributed queries");
207  }
208  if (g_enable_watchdog) {
209  throw WatchdogException(
210  "Cast from none-encoded string to dictionary-encoded would be slow");
211  }
212  CHECK_EQ(kENCODING_NONE, operand_ti.get_compression());
214  CHECK(operand_lv->getType()->isIntegerTy(64));
216  throw QueryMustRunOnCpu();
217  }
219  "string_compress",
221  {operand_lv,
222  cgen_state_->llInt(int64_t(executor()->getStringDictionaryProxy(
223  ti.get_comp_param(), executor()->getRowSetMemoryOwner(), true)))});
224  }
225  CHECK(operand_lv->getType()->isIntegerTy(32));
226  if (ti.get_compression() == kENCODING_NONE) {
227  if (g_cluster) {
228  throw std::runtime_error(
229  "Cast from dictionary-encoded string to none-encoded not supported for "
230  "distributed queries");
231  }
232  if (g_enable_watchdog) {
233  throw WatchdogException(
234  "Cast from dictionary-encoded string to none-encoded would be slow");
235  }
236  CHECK_EQ(kENCODING_DICT, operand_ti.get_compression());
238  throw QueryMustRunOnCpu();
239  }
240  const int64_t string_dictionary_ptr =
241  operand_ti.get_comp_param() == 0
242  ? reinterpret_cast<int64_t>(
243  executor()->getRowSetMemoryOwner()->getLiteralStringDictProxy())
244  : reinterpret_cast<int64_t>(executor()->getStringDictionaryProxy(
245  operand_ti.get_comp_param(), executor()->getRowSetMemoryOwner(), true));
247  "string_decompress",
249  {operand_lv, cgen_state_->llInt(string_dictionary_ptr)});
250  }
251  CHECK(operand_is_const);
252  CHECK_EQ(kENCODING_DICT, ti.get_compression());
253  return operand_lv;
254 }
255 
256 llvm::Value* CodeGenerator::codegenCastBetweenIntTypes(llvm::Value* operand_lv,
257  const SQLTypeInfo& operand_ti,
258  const SQLTypeInfo& ti,
259  bool upscale) {
261  if (ti.is_decimal() &&
262  (!operand_ti.is_decimal() || operand_ti.get_scale() <= ti.get_scale())) {
263  if (upscale) {
264  if (operand_ti.get_scale() < ti.get_scale()) { // scale only if needed
265  auto scale = exp_to_scale(ti.get_scale() - operand_ti.get_scale());
266  const auto scale_lv =
267  llvm::ConstantInt::get(get_int_type(64, cgen_state_->context_), scale);
268  operand_lv = cgen_state_->ir_builder_.CreateSExt(
269  operand_lv, get_int_type(64, cgen_state_->context_));
270 
271  codegenCastBetweenIntTypesOverflowChecks(operand_lv, operand_ti, ti, scale);
272 
273  if (operand_ti.get_notnull()) {
274  operand_lv = cgen_state_->ir_builder_.CreateMul(operand_lv, scale_lv);
275  } else {
276  operand_lv = cgen_state_->emitCall(
277  "scale_decimal_up",
278  {operand_lv,
279  scale_lv,
280  cgen_state_->llInt(inline_int_null_val(operand_ti)),
282  }
283  }
284  }
285  } else if (operand_ti.is_decimal()) {
286  // rounded scale down
287  auto scale = (int64_t)exp_to_scale(operand_ti.get_scale() - ti.get_scale());
288  const auto scale_lv =
289  llvm::ConstantInt::get(get_int_type(64, cgen_state_->context_), scale);
290 
291  const auto operand_width =
292  static_cast<llvm::IntegerType*>(operand_lv->getType())->getBitWidth();
293 
294  std::string method_name = "scale_decimal_down_nullable";
295  if (operand_ti.get_notnull()) {
296  method_name = "scale_decimal_down_not_nullable";
297  }
298 
299  CHECK(operand_width == 64);
300  operand_lv = cgen_state_->emitCall(
301  method_name,
302  {operand_lv, scale_lv, cgen_state_->llInt(inline_int_null_val(operand_ti))});
303  }
304  if (ti.is_integer() && operand_ti.is_integer() &&
305  operand_ti.get_logical_size() > ti.get_logical_size()) {
306  codegenCastBetweenIntTypesOverflowChecks(operand_lv, operand_ti, ti, 1);
307  }
308 
309  const auto operand_width =
310  static_cast<llvm::IntegerType*>(operand_lv->getType())->getBitWidth();
311  const auto target_width = get_bit_width(ti);
312  if (target_width == operand_width) {
313  return operand_lv;
314  }
315  if (operand_ti.get_notnull()) {
316  return cgen_state_->ir_builder_.CreateCast(
317  target_width > operand_width ? llvm::Instruction::CastOps::SExt
318  : llvm::Instruction::CastOps::Trunc,
319  operand_lv,
320  get_int_type(target_width, cgen_state_->context_));
321  }
322  return cgen_state_->emitCall("cast_" + numeric_type_name(operand_ti) + "_to_" +
323  numeric_type_name(ti) + "_nullable",
324  {operand_lv,
325  cgen_state_->inlineIntNull(operand_ti),
326  cgen_state_->inlineIntNull(ti)});
327 }
328 
330  llvm::Value* operand_lv,
331  const SQLTypeInfo& operand_ti,
332  const SQLTypeInfo& ti,
333  const int64_t scale) {
335  llvm::Value* chosen_max{nullptr};
336  llvm::Value* chosen_min{nullptr};
337  std::tie(chosen_max, chosen_min) =
339 
341  auto cast_ok = llvm::BasicBlock::Create(
343  auto cast_fail = llvm::BasicBlock::Create(
345  auto operand_max = static_cast<llvm::ConstantInt*>(chosen_max)->getSExtValue() / scale;
346  auto operand_min = static_cast<llvm::ConstantInt*>(chosen_min)->getSExtValue() / scale;
347  const auto ti_llvm_type =
349  llvm::Value* operand_max_lv = llvm::ConstantInt::get(ti_llvm_type, operand_max);
350  llvm::Value* operand_min_lv = llvm::ConstantInt::get(ti_llvm_type, operand_min);
351  const bool is_narrowing = operand_ti.get_logical_size() > ti.get_logical_size();
352  if (is_narrowing) {
353  const auto operand_ti_llvm_type =
355  operand_max_lv =
356  cgen_state_->ir_builder_.CreateSExt(operand_max_lv, operand_ti_llvm_type);
357  operand_min_lv =
358  cgen_state_->ir_builder_.CreateSExt(operand_min_lv, operand_ti_llvm_type);
359  }
360  llvm::Value* over{nullptr};
361  llvm::Value* under{nullptr};
362  if (operand_ti.get_notnull()) {
363  over = cgen_state_->ir_builder_.CreateICmpSGT(operand_lv, operand_max_lv);
364  under = cgen_state_->ir_builder_.CreateICmpSLE(operand_lv, operand_min_lv);
365  } else {
366  const auto type_name =
367  is_narrowing ? numeric_type_name(operand_ti) : numeric_type_name(ti);
368  const auto null_operand_val = cgen_state_->llInt(inline_int_null_val(operand_ti));
369  const auto null_bool_val = cgen_state_->inlineIntNull(SQLTypeInfo(kBOOLEAN, false));
370  over = toBool(cgen_state_->emitCall(
371  "gt_" + type_name + "_nullable_lhs",
372  {operand_lv, operand_max_lv, null_operand_val, null_bool_val}));
373  under = toBool(cgen_state_->emitCall(
374  "le_" + type_name + "_nullable_lhs",
375  {operand_lv, operand_min_lv, null_operand_val, null_bool_val}));
376  }
377  const auto detected = cgen_state_->ir_builder_.CreateOr(over, under, "overflow");
378  cgen_state_->ir_builder_.CreateCondBr(detected, cast_fail, cast_ok);
379 
380  cgen_state_->ir_builder_.SetInsertPoint(cast_fail);
381  cgen_state_->ir_builder_.CreateRet(
382  cgen_state_->llInt(Executor::ERR_OVERFLOW_OR_UNDERFLOW));
383 
384  cgen_state_->ir_builder_.SetInsertPoint(cast_ok);
385 }
386 
387 llvm::Value* CodeGenerator::codegenCastToFp(llvm::Value* operand_lv,
388  const SQLTypeInfo& operand_ti,
389  const SQLTypeInfo& ti) {
391  if (!ti.is_fp()) {
392  throw std::runtime_error("Cast from " + operand_ti.get_type_name() + " to " +
393  ti.get_type_name() + " not supported");
394  }
395  const auto to_tname = numeric_type_name(ti);
396  llvm::Value* result_lv{nullptr};
397  if (operand_ti.get_notnull()) {
398  result_lv = cgen_state_->ir_builder_.CreateSIToFP(
399  operand_lv,
400  ti.get_type() == kFLOAT ? llvm::Type::getFloatTy(cgen_state_->context_)
401  : llvm::Type::getDoubleTy(cgen_state_->context_));
402  } else {
403  result_lv = cgen_state_->emitCall(
404  "cast_" + numeric_type_name(operand_ti) + "_to_" + to_tname + "_nullable",
405  {operand_lv,
406  cgen_state_->inlineIntNull(operand_ti),
407  cgen_state_->inlineFpNull(ti)});
408  }
409  CHECK(result_lv);
410  if (operand_ti.get_scale()) {
411  result_lv = cgen_state_->ir_builder_.CreateFDiv(
412  result_lv,
413  llvm::ConstantFP::get(result_lv->getType(),
414  exp_to_scale(operand_ti.get_scale())));
415  }
416  return result_lv;
417 }
418 
419 llvm::Value* CodeGenerator::codegenCastFromFp(llvm::Value* operand_lv,
420  const SQLTypeInfo& operand_ti,
421  const SQLTypeInfo& ti) {
423  if (!operand_ti.is_fp() || !ti.is_number() || ti.is_decimal()) {
424  throw std::runtime_error("Cast from " + operand_ti.get_type_name() + " to " +
425  ti.get_type_name() + " not supported");
426  }
427  if (operand_ti.get_type() == ti.get_type()) {
428  // Should not have been called when both dimensions are same.
429  return operand_lv;
430  }
431  CHECK(operand_lv->getType()->isFloatTy() || operand_lv->getType()->isDoubleTy());
432  if (operand_ti.get_notnull()) {
433  if (ti.get_type() == kDOUBLE) {
434  return cgen_state_->ir_builder_.CreateFPExt(
435  operand_lv, llvm::Type::getDoubleTy(cgen_state_->context_));
436  } else if (ti.get_type() == kFLOAT) {
437  return cgen_state_->ir_builder_.CreateFPTrunc(
438  operand_lv, llvm::Type::getFloatTy(cgen_state_->context_));
439  } else if (ti.is_integer()) {
440  return cgen_state_->ir_builder_.CreateFPToSI(
441  operand_lv, get_int_type(get_bit_width(ti), cgen_state_->context_));
442  } else {
443  CHECK(false);
444  }
445  } else {
446  const auto from_tname = numeric_type_name(operand_ti);
447  const auto to_tname = numeric_type_name(ti);
448  if (ti.is_fp()) {
449  return cgen_state_->emitCall("cast_" + from_tname + "_to_" + to_tname + "_nullable",
450  {operand_lv,
451  cgen_state_->inlineFpNull(operand_ti),
452  cgen_state_->inlineFpNull(ti)});
453  } else if (ti.is_integer()) {
454  return cgen_state_->emitCall("cast_" + from_tname + "_to_" + to_tname + "_nullable",
455  {operand_lv,
456  cgen_state_->inlineFpNull(operand_ti),
457  cgen_state_->inlineIntNull(ti)});
458  } else {
459  CHECK(false);
460  }
461  }
462  CHECK(false);
463  return nullptr;
464 }
HOST DEVICE SQLTypes get_subtype() const
Definition: sqltypes.h:260
#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:419
HOST DEVICE int get_size() const
Definition: sqltypes.h:269
bool g_enable_watchdog
bool is_timestamp() const
Definition: sqltypes.h:654
CgenState * cgen_state_
#define NULL_BIGINT
Definition: sqltypes.h:184
bool is_fp() const
Definition: sqltypes.h:421
HOST DEVICE int get_scale() const
Definition: sqltypes.h:264
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:222
llvm::ConstantInt * ll_int(const T v, llvm::LLVMContext &context)
llvm::IRBuilder ir_builder_
Definition: CgenState.h:341
llvm::Value * codegenCastToFp(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
Definition: CastIR.cpp:387
Definition: sqldefs.h:49
bool byte_array_cast(const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti)
Definition: CastIR.cpp:47
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:259
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
bool is_number() const
Definition: sqltypes.h:422
bool is_time() const
Definition: sqltypes.h:423
size_t get_bit_width(const SQLTypeInfo &ti)
llvm::LLVMContext & context_
Definition: CgenState.h:339
llvm::Function * current_func_
Definition: CgenState.h:333
int get_logical_size() const
Definition: sqltypes.h:270
bool is_integer() const
Definition: sqltypes.h:419
llvm::ConstantInt * inlineIntNull(const SQLTypeInfo &)
Definition: CgenState.cpp:27
static const int32_t ERR_OVERFLOW_OR_UNDERFLOW
Definition: Execute.h:987
llvm::Value * codegenCastBetweenIntTypes(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, bool upscale=true)
Definition: CastIR.cpp:256
bool needs_error_check_
Definition: CgenState.h:356
bool is_boolean() const
Definition: sqltypes.h:424
llvm::Value * codegenCastTimestampToDate(llvm::Value *ts_lv, const int dimen, const bool nullable)
Definition: CastIR.cpp:118
#define AUTOMATIC_IR_METADATA(CGENSTATE)
const SQLTypeInfo & get_type_info() const
Definition: Analyzer.h:78
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:55
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:267
const Expr * get_operand() const
Definition: Analyzer.h:371
void codegenCastBetweenIntTypesOverflowChecks(llvm::Value *operand_lv, const SQLTypeInfo &operand_ti, const SQLTypeInfo &ti, const int64_t scale)
Definition: CastIR.cpp:329
HOST DEVICE int get_dimension() const
Definition: sqltypes.h:261
std::string get_type_name() const
Definition: sqltypes.h:362
llvm::Value * toBool(llvm::Value *)
Definition: LogicalIR.cpp:335
HOST DEVICE int get_comp_param() const
Definition: sqltypes.h:268
llvm::Value * codegenCastBetweenTimestamps(llvm::Value *ts_lv, const SQLTypeInfo &operand_dimen, const SQLTypeInfo &target_dimen, const bool nullable)
Definition: CastIR.cpp:155
llvm::ConstantInt * llInt(const T v) const
Definition: CgenState.h:312
#define CHECK(condition)
Definition: Logger.h:197
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:187
llvm::Value * codegenCast(const Analyzer::UOper *, const CompilationOptions &)
Definition: CastIR.cpp:20
std::string numeric_type_name(const SQLTypeInfo &ti)
Definition: Execute.h:172
bool is_string() const
Definition: sqltypes.h:417
HOST DEVICE bool get_notnull() const
Definition: sqltypes.h:266
llvm::ArrayType * get_int_array_type(int const width, int count, llvm::LLVMContext &context)
bool is_decimal() const
Definition: sqltypes.h:420
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:370
bool is_array() const
Definition: sqltypes.h:425
llvm::ConstantFP * inlineFpNull(const SQLTypeInfo &)
Definition: CgenState.cpp:65
Executor * executor() const