OmniSciDB  fe05a0c208
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Datum.cpp File Reference
#include <algorithm>
#include <cassert>
#include <cctype>
#include <charconv>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <limits>
#include <stdexcept>
#include <string>
#include "DateConverters.h"
#include "DateTimeParser.h"
#include "Logger/Logger.h"
#include "QueryEngine/DateTimeUtils.h"
#include "StringTransform.h"
#include "misc.h"
#include "sqltypes.h"
+ Include dependency graph for Datum.cpp:

Go to the source code of this file.

Namespaces

 anonymous_namespace{Datum.cpp}
 

Functions

int64_t parse_numeric (const std::string_view s, SQLTypeInfo &ti)
 
template<typename T >
anonymous_namespace{Datum.cpp}::minValue (unsigned const fieldsize)
 
template<typename T >
anonymous_namespace{Datum.cpp}::maxValue (unsigned const fieldsize)
 
std::string anonymous_namespace{Datum.cpp}::toString (SQLTypeInfo const &ti, unsigned const fieldsize)
 
template<typename T , typename U = long double>
anonymous_namespace{Datum.cpp}::parseFloatAsInteger (std::string_view s, SQLTypeInfo const &ti)
 
bool anonymous_namespace{Datum.cpp}::hasCommonSuffix (char const *const ptr, char const *const end)
 
template<typename T >
anonymous_namespace{Datum.cpp}::parseInteger (std::string_view s, SQLTypeInfo const &ti)
 
Datum StringToDatum (std::string_view s, SQLTypeInfo &ti)
 
bool DatumEqual (const Datum a, const Datum b, const SQLTypeInfo &ti)
 
std::string DatumToString (Datum d, const SQLTypeInfo &ti)
 
SQLTypes decimal_to_int_type (const SQLTypeInfo &ti)
 
int64_t convert_decimal_value_to_scale (const int64_t decimal_value, const SQLTypeInfo &type_info, const SQLTypeInfo &new_type_info)
 

Function Documentation

int64_t convert_decimal_value_to_scale ( const int64_t  decimal_value,
const SQLTypeInfo type_info,
const SQLTypeInfo new_type_info 
)

Definition at line 437 of file Datum.cpp.

References SQLTypeInfo::get_scale().

Referenced by import_export::TypedImportBuffer::add_value(), Analyzer::Constant::cast_number(), anonymous_namespace{ArrowImporter.h}::ArrowValue< arrow::Decimal128 >::operator DATA_TYPE(), and anonymous_namespace{TypedDataAccessors.h}::put_scalar().

439  {
440  constexpr int max_scale = std::numeric_limits<uint64_t>::digits10; // 19
441  constexpr auto pow10 = shared::powersOf<uint64_t, max_scale + 1>(10);
442  int const dscale = new_type_info.get_scale() - type_info.get_scale();
443  if (dscale < 0) {
444  if (dscale < -max_scale) {
445  return 0; // +/- 0.09223372036854775807 rounds to 0
446  }
447  uint64_t const u = std::abs(decimal_value);
448  uint64_t const pow = pow10[-dscale];
449  uint64_t div = u / pow;
450  uint64_t rem = u % pow;
451  div += pow / 2 <= rem;
452  return decimal_value < 0 ? -div : div;
453  } else if (dscale < max_scale) {
454  int64_t retval;
455  if (!__builtin_mul_overflow(decimal_value, pow10[dscale], &retval)) {
456  return retval;
457  }
458  }
459  if (decimal_value == 0) {
460  return 0;
461  }
462  throw std::runtime_error("Overflow in DECIMAL-to-DECIMAL conversion.");
463 }
HOST DEVICE int get_scale() const
Definition: sqltypes.h:319

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool DatumEqual ( const Datum  a,
const Datum  b,
const SQLTypeInfo ti 
)

Definition at line 306 of file Datum.cpp.

References Datum::bigintval, Datum::boolval, Datum::doubleval, Datum::floatval, SQLTypeInfo::get_compression(), SQLTypeInfo::get_type(), Datum::intval, kBIGINT, kBOOLEAN, kCHAR, kDATE, kDECIMAL, kDOUBLE, kENCODING_DICT, kFLOAT, kINT, kINTERVAL_DAY_TIME, kINTERVAL_YEAR_MONTH, kLINESTRING, kMULTIPOLYGON, kNUMERIC, kPOINT, kPOLYGON, kSMALLINT, kTEXT, kTIME, kTIMESTAMP, kTINYINT, kVARCHAR, Datum::smallintval, Datum::stringval, and Datum::tinyintval.

Referenced by ChunkMetadata::operator==(), FixedLengthArrayNoneEncoder::resetChunkStats(), and ArrayNoneEncoder::resetChunkStats().

306  {
307  switch (ti.get_type()) {
308  case kBOOLEAN:
309  return a.boolval == b.boolval;
310  case kBIGINT:
311  case kNUMERIC:
312  case kDECIMAL:
313  return a.bigintval == b.bigintval;
314  case kINT:
315  return a.intval == b.intval;
316  case kSMALLINT:
317  return a.smallintval == b.smallintval;
318  case kTINYINT:
319  return a.tinyintval == b.tinyintval;
320  case kFLOAT:
321  return a.floatval == b.floatval;
322  case kDOUBLE:
323  return a.doubleval == b.doubleval;
324  case kTIME:
325  case kTIMESTAMP:
326  case kDATE:
327  case kINTERVAL_DAY_TIME:
329  return a.bigintval == b.bigintval;
330  case kTEXT:
331  case kVARCHAR:
332  case kCHAR:
333  case kPOINT:
334  case kLINESTRING:
335  case kPOLYGON:
336  case kMULTIPOLYGON:
337  if (ti.get_compression() == kENCODING_DICT) {
338  return a.intval == b.intval;
339  }
340  if (a.stringval == nullptr && b.stringval == nullptr) {
341  return true;
342  }
343  if (a.stringval == nullptr || b.stringval == nullptr) {
344  return false;
345  }
346  return *a.stringval == *b.stringval;
347  default:
348  return false;
349  }
350  return false;
351 }
int8_t tinyintval
Definition: sqltypes.h:206
Definition: sqltypes.h:48
bool boolval
Definition: sqltypes.h:205
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:314
int32_t intval
Definition: sqltypes.h:208
float floatval
Definition: sqltypes.h:210
int64_t bigintval
Definition: sqltypes.h:209
int16_t smallintval
Definition: sqltypes.h:207
std::string * stringval
Definition: sqltypes.h:214
Definition: sqltypes.h:51
Definition: sqltypes.h:52
HOST DEVICE EncodingType get_compression() const
Definition: sqltypes.h:322
Definition: sqltypes.h:40
Definition: sqltypes.h:44
double doubleval
Definition: sqltypes.h:211

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string DatumToString ( Datum  d,
const SQLTypeInfo ti 
)

Definition at line 356 of file Datum.cpp.

References Datum::bigintval, Datum::boolval, CHECK_EQ, CHECK_LE, CHECK_LT, Datum::doubleval, Datum::floatval, shared::formatDate(), shared::formatDateTime(), shared::formatHMS(), SQLTypeInfo::get_dimension(), SQLTypeInfo::get_scale(), SQLTypeInfo::get_type(), SQLTypeInfo::get_type_name(), Datum::intval, kBIGINT, kBOOLEAN, kCHAR, kDATE, kDECIMAL, kDOUBLE, kFLOAT, kINT, kINTERVAL_DAY_TIME, kINTERVAL_YEAR_MONTH, kNUMERIC, kSMALLINT, kTEXT, kTIME, kTIMESTAMP, kTINYINT, kVARCHAR, Datum::smallintval, Datum::stringval, Datum::tinyintval, to_string(), and SQLTypeInfo::to_string().

Referenced by Analyzer::Constant::cast_to_string(), foreign_storage::datetime_to_string(), ChunkMetadata::dump(), anonymous_namespace{ArrowImporter.h}::ArrowValue< int64_t >::operator DATA_TYPE(), import_export::anonymous_namespace{QueryExporterCSV.cpp}::target_value_to_string(), Analyzer::Constant::toString(), Fragmenter_Namespace::InsertOrderFragmenter::updateChunkStats(), and ScalarExprToSql::visitConstant().

356  {
357  constexpr size_t buf_size = 64;
358  char buf[buf_size]; // Hold "2000-03-01 12:34:56.123456789" and large years.
359  switch (ti.get_type()) {
360  case kBOOLEAN:
361  if (d.boolval) {
362  return "t";
363  }
364  return "f";
365  case kNUMERIC:
366  case kDECIMAL: {
367  double v = (double)d.bigintval / pow(10, ti.get_scale());
368  int size = snprintf(buf, buf_size, "%*.*f", ti.get_dimension(), ti.get_scale(), v);
369  CHECK_LE(0, size) << v << ' ' << ti.to_string();
370  CHECK_LT(size_t(size), buf_size) << v << ' ' << ti.to_string();
371  return buf;
372  }
373  case kINT:
374  return std::to_string(d.intval);
375  case kSMALLINT:
376  return std::to_string(d.smallintval);
377  case kTINYINT:
378  return std::to_string(d.tinyintval);
379  case kBIGINT:
380  return std::to_string(d.bigintval);
381  case kFLOAT:
382  return std::to_string(d.floatval);
383  case kDOUBLE:
384  return std::to_string(d.doubleval);
385  case kTIME: {
386  size_t const len = shared::formatHMS(buf, buf_size, d.bigintval);
387  CHECK_EQ(8u, len); // 8 == strlen("HH:MM:SS")
388  return buf;
389  }
390  case kTIMESTAMP: {
391  unsigned const dim = ti.get_dimension(); // assumes dim <= 9
392  size_t const len = shared::formatDateTime(buf, buf_size, d.bigintval, dim);
393  CHECK_LE(19u + bool(dim) + dim, len); // 19 = strlen("YYYY-MM-DD HH:MM:SS")
394  return buf;
395  }
396  case kDATE: {
397  size_t const len = shared::formatDate(buf, buf_size, d.bigintval);
398  CHECK_LE(10u, len); // 10 == strlen("YYYY-MM-DD")
399  return buf;
400  }
401  case kINTERVAL_DAY_TIME:
402  return std::to_string(d.bigintval) + " ms (day-time interval)";
404  return std::to_string(d.bigintval) + " month(s) (year-month interval)";
405  case kTEXT:
406  case kVARCHAR:
407  case kCHAR:
408  if (d.stringval == nullptr) {
409  return "NULL";
410  }
411  return *d.stringval;
412  default:
413  throw std::runtime_error("Internal error: invalid type " + ti.get_type_name() +
414  " in DatumToString.");
415  }
416  return "";
417 }
int8_t tinyintval
Definition: sqltypes.h:206
#define CHECK_EQ(x, y)
Definition: Logger.h:211
Definition: sqltypes.h:48
bool boolval
Definition: sqltypes.h:205
HOST DEVICE int get_scale() const
Definition: sqltypes.h:319
size_t formatDateTime(char *buf, size_t const max, int64_t const timestamp, int const dimension)
Definition: misc.cpp:43
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:314
int32_t intval
Definition: sqltypes.h:208
std::string to_string(char const *&&v)
size_t formatHMS(char *buf, size_t const max, int64_t const unixtime)
Definition: misc.cpp:80
float floatval
Definition: sqltypes.h:210
std::string to_string() const
Definition: sqltypes.h:457
int64_t bigintval
Definition: sqltypes.h:209
int16_t smallintval
Definition: sqltypes.h:207
std::string * stringval
Definition: sqltypes.h:214
size_t formatDate(char *buf, size_t const max, int64_t const unixtime)
Definition: misc.cpp:25
#define CHECK_LT(x, y)
Definition: Logger.h:213
Definition: sqltypes.h:51
Definition: sqltypes.h:52
#define CHECK_LE(x, y)
Definition: Logger.h:214
HOST DEVICE int get_dimension() const
Definition: sqltypes.h:316
std::string get_type_name() const
Definition: sqltypes.h:417
Definition: sqltypes.h:40
Definition: sqltypes.h:44
double doubleval
Definition: sqltypes.h:211

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

SQLTypes decimal_to_int_type ( const SQLTypeInfo ti)

Definition at line 419 of file Datum.cpp.

References CHECK, SQLTypeInfo::get_size(), kBIGINT, kINT, kNULLT, kSMALLINT, and kTINYINT.

Referenced by import_export::TypedImportBuffer::add_value(), CodeGenerator::codegen(), CodeGenerator::codegenIntConst(), anonymous_namespace{LogicalIR.cpp}::contains_unsafe_division(), extract_from_datum(), import_export::Loader::fillShardRow(), anonymous_namespace{ColumnIR.cpp}::get_col_decoder(), CgenState::getOrAddLiteral(), ResultSet::makeTargetValue(), import_export::NullArrayDatum(), import_export::NullDatum(), import_export::TypedImportBuffer::pop_value(), import_export::TDatumToDatum(), anonymous_namespace{ExpressionRewrite.cpp}::ConstantFoldingVisitor::visitBinOper(), and anonymous_namespace{ExpressionRewrite.cpp}::ConstantFoldingVisitor::visitUOper().

419  {
420  switch (ti.get_size()) {
421  case 1:
422  return kTINYINT;
423  case 2:
424  return kSMALLINT;
425  case 4:
426  return kINT;
427  case 8:
428  return kBIGINT;
429  default:
430  CHECK(false);
431  }
432  return kNULLT;
433 }
HOST DEVICE int get_size() const
Definition: sqltypes.h:324
#define CHECK(condition)
Definition: Logger.h:203
Definition: sqltypes.h:44

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int64_t parse_numeric ( const std::string_view  s,
SQLTypeInfo ti 
)

Definition at line 75 of file Datum.cpp.

References CHECK_GE, SQLTypeInfo::get_dimension(), SQLTypeInfo::get_scale(), i, run_benchmark_import::result, SQLTypeInfo::set_dimension(), SQLTypeInfo::set_notnull(), SQLTypeInfo::set_scale(), and to_string().

Referenced by StringToDatum().

75  {
76  assert(s.length() <= 20);
77  size_t dot = s.find_first_of('.', 0);
78  std::string before_dot;
79  std::string after_dot;
80  if (dot != std::string::npos) {
81  // make .99 as 0.99, or std::stoll below throws exception 'std::invalid_argument'
82  before_dot = (0 == dot) ? "0" : s.substr(0, dot);
83  after_dot = s.substr(dot + 1);
84  } else {
85  before_dot = s;
86  after_dot = "0";
87  }
88  const bool is_negative = before_dot.find_first_of('-', 0) != std::string::npos;
89  const int64_t sign = is_negative ? -1 : 1;
90  int64_t result;
91  result = std::abs(std::stoll(before_dot));
92  int64_t fraction = 0;
93  const size_t before_dot_digits = before_dot.length() - (is_negative ? 1 : 0);
94  if (!after_dot.empty()) {
95  fraction = std::stoll(after_dot);
96  }
97  if (ti.get_dimension() == 0) {
98  // set the type info based on the literal string
99  ti.set_scale(static_cast<int>(after_dot.length()));
100  ti.set_dimension(static_cast<int>(before_dot_digits + ti.get_scale()));
101  ti.set_notnull(false);
102  } else {
103  CHECK_GE(ti.get_scale(), 0);
104  if (before_dot_digits + ti.get_scale() > static_cast<size_t>(ti.get_dimension())) {
105  throw std::runtime_error("numeric value " + std::string(s) +
106  " exceeds the maximum precision of " +
108  }
109  for (size_t i = static_cast<size_t>(ti.get_scale()); i < after_dot.length(); ++i) {
110  fraction /= 10; // truncate the digits after decimal point.
111  }
112  }
113  // the following loop can be made more efficient if needed
114  for (int i = 0; i < ti.get_scale(); i++) {
115  result *= 10;
116  }
117  if (result < 0) {
118  result -= fraction;
119  } else {
120  result += fraction;
121  }
122  return result * sign;
123 }
HOST DEVICE int get_scale() const
Definition: sqltypes.h:319
#define CHECK_GE(x, y)
Definition: Logger.h:216
std::string to_string(char const *&&v)
void set_scale(int s)
Definition: sqltypes.h:409
void set_dimension(int d)
Definition: sqltypes.h:406
HOST DEVICE int get_dimension() const
Definition: sqltypes.h:316
void set_notnull(bool n)
Definition: sqltypes.h:411

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Datum StringToDatum ( std::string_view  s,
SQLTypeInfo ti 
)

Definition at line 239 of file Datum.cpp.

References Datum::bigintval, Datum::boolval, test_fsi::d, Datum::doubleval, Datum::floatval, SQLTypeInfo::get_dimension(), SQLTypeInfo::get_type(), SQLTypeInfo::get_type_name(), Datum::intval, kARRAY, kBIGINT, kBOOLEAN, kCOLUMN, kCOLUMN_LIST, kDATE, kDECIMAL, kDOUBLE, kFLOAT, kINT, kLINESTRING, kMULTIPOLYGON, kNUMERIC, kPOINT, kPOLYGON, kSMALLINT, kTIME, kTIMESTAMP, kTINYINT, parse_numeric(), Datum::smallintval, Datum::tinyintval, and to_upper().

Referenced by import_export::TypedImportBuffer::add_value(), Parser::FixedPtLiteral::analyze(), Analyzer::Constant::cast_from_string(), anonymous_namespace{ArrowImporter.h}::ArrowValue< std::string >::operator DATA_TYPE(), populate_TColumn(), and import_export::StringToArray().

239  {
240  Datum d;
241  try {
242  switch (ti.get_type()) {
243  case kARRAY:
244  case kCOLUMN:
245  case kCOLUMN_LIST:
246  break;
247  case kBOOLEAN:
248  if (s == "t" || s == "T" || s == "1" || to_upper(std::string(s)) == "TRUE") {
249  d.boolval = true;
250  } else if (s == "f" || s == "F" || s == "0" ||
251  to_upper(std::string(s)) == "FALSE") {
252  d.boolval = false;
253  } else {
254  throw std::runtime_error("Invalid string for boolean " + std::string(s));
255  }
256  break;
257  case kNUMERIC:
258  case kDECIMAL:
259  d.bigintval = parse_numeric(s, ti);
260  break;
261  case kBIGINT:
262  d.bigintval = parseInteger<int64_t>(s, ti);
263  break;
264  case kINT:
265  d.intval = parseInteger<int32_t>(s, ti);
266  break;
267  case kSMALLINT:
268  d.smallintval = parseInteger<int16_t>(s, ti);
269  break;
270  case kTINYINT:
271  d.tinyintval = parseInteger<int8_t>(s, ti);
272  break;
273  case kFLOAT:
274  d.floatval = std::stof(std::string(s));
275  break;
276  case kDOUBLE:
277  d.doubleval = std::stod(std::string(s));
278  break;
279  case kTIME:
280  d.bigintval = dateTimeParse<kTIME>(s, ti.get_dimension());
281  break;
282  case kTIMESTAMP:
283  d.bigintval = dateTimeParse<kTIMESTAMP>(s, ti.get_dimension());
284  break;
285  case kDATE:
286  d.bigintval = dateTimeParse<kDATE>(s, ti.get_dimension());
287  break;
288  case kPOINT:
289  case kLINESTRING:
290  case kPOLYGON:
291  case kMULTIPOLYGON:
292  throw std::runtime_error("Internal error: geometry type in StringToDatum.");
293  default:
294  throw std::runtime_error("Internal error: invalid type in StringToDatum: " +
295  ti.get_type_name());
296  }
297  } catch (const std::invalid_argument&) {
298  throw std::runtime_error("Invalid conversion from string to " + ti.get_type_name());
299  } catch (const std::out_of_range&) {
300  throw std::runtime_error("Got out of range error during conversion from string to " +
301  ti.get_type_name());
302  }
303  return d;
304 }
int8_t tinyintval
Definition: sqltypes.h:206
Definition: sqltypes.h:48
tuple d
Definition: test_fsi.py:9
int64_t parse_numeric(const std::string_view s, SQLTypeInfo &ti)
Definition: Datum.cpp:75
bool boolval
Definition: sqltypes.h:205
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:314
int32_t intval
Definition: sqltypes.h:208
float floatval
Definition: sqltypes.h:210
int64_t bigintval
Definition: sqltypes.h:209
int16_t smallintval
Definition: sqltypes.h:207
std::string to_upper(const std::string &str)
Definition: sqltypes.h:52
HOST DEVICE int get_dimension() const
Definition: sqltypes.h:316
std::string get_type_name() const
Definition: sqltypes.h:417
Definition: sqltypes.h:44
double doubleval
Definition: sqltypes.h:211

+ Here is the call graph for this function:

+ Here is the caller graph for this function: