OmniSciDB  a987f07e93
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
anonymous_namespace{Datum.cpp} Namespace Reference

Functions

int64_t convert_decimal_value_to_scale_internal (const int64_t decimal_value, int const dscale)
 
template<typename T >
minValue (unsigned const fieldsize)
 
template<typename T >
maxValue (unsigned const fieldsize)
 
std::string toString (SQLTypeInfo const &ti, unsigned const fieldsize)
 
template<typename T , typename U = long double>
parseFloatAsInteger (std::string_view s, SQLTypeInfo const &ti)
 
bool hasCommonSuffix (char const *const ptr, char const *const end)
 
template<typename T >
parseInteger (std::string_view s, SQLTypeInfo const &ti)
 
SQLTypes get_type_for_datum (const SQLTypeInfo &ti)
 

Function Documentation

int64_t anonymous_namespace{Datum.cpp}::convert_decimal_value_to_scale_internal ( const int64_t  decimal_value,
int const  dscale 
)

Definition at line 79 of file Datum.cpp.

References sql_constants::kMaxRepresentableNumericPrecision.

Referenced by convert_decimal_value_to_scale(), and parse_numeric().

80  {
81  constexpr int max_scale = sql_constants::kMaxRepresentableNumericPrecision; // 19
82  constexpr auto pow10 = shared::powersOf<uint64_t, max_scale + 1>(10);
83  if (dscale < 0) {
84  if (dscale < -max_scale) {
85  return 0; // +/- 0.09223372036854775807 rounds to 0
86  }
87  uint64_t const u = std::abs(decimal_value);
88  uint64_t const pow = pow10[-dscale];
89  uint64_t div = u / pow;
90  uint64_t rem = u % pow;
91  div += pow / 2 <= rem;
92  return decimal_value < 0 ? -div : div;
93  } else if (dscale < max_scale) {
94  int64_t retval;
95 #ifdef _WIN32
96  return decimal_value * pow10[dscale];
97 #else
98  if (!__builtin_mul_overflow(decimal_value, pow10[dscale], &retval)) {
99  return retval;
100  }
101 #endif
102  }
103  if (decimal_value == 0) {
104  return 0;
105  }
106  throw std::runtime_error("Overflow in DECIMAL-to-DECIMAL conversion.");
107 }
static constexpr int32_t kMaxRepresentableNumericPrecision
Definition: sqltypes.h:48

+ Here is the caller graph for this function:

SQLTypes anonymous_namespace{Datum.cpp}::get_type_for_datum ( const SQLTypeInfo ti)
inline

Definition at line 272 of file Datum.cpp.

References decimal_to_int_type(), SQLTypeInfo::get_type(), SQLTypeInfo::is_decimal(), SQLTypeInfo::is_dict_encoded_string(), string_dict_to_int_type(), and run_benchmark_import::type.

272  {
273  SQLTypes type;
274  if (ti.is_decimal()) {
275  type = decimal_to_int_type(ti);
276  } else if (ti.is_dict_encoded_string()) {
277  type = string_dict_to_int_type(ti);
278  } else {
279  type = ti.get_type();
280  }
281  return type;
282 }
SQLTypes
Definition: sqltypes.h:53
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:380
SQLTypes decimal_to_int_type(const SQLTypeInfo &ti)
Definition: Datum.cpp:559
bool is_dict_encoded_string() const
Definition: sqltypes.h:628
bool is_decimal() const
Definition: sqltypes.h:579
SQLTypes string_dict_to_int_type(const SQLTypeInfo &ti)
Definition: Datum.cpp:563

+ Here is the call graph for this function:

bool anonymous_namespace{Datum.cpp}::hasCommonSuffix ( char const *const  ptr,
char const *const  end 
)
inline

Definition at line 224 of file Datum.cpp.

Referenced by parseInteger().

224  {
225  return *ptr == '.' && (ptr + 1 == end || (ptr[1] == '0' && ptr + 2 == end));
226 }

+ Here is the caller graph for this function:

template<typename T >
T anonymous_namespace{Datum.cpp}::maxValue ( unsigned const  fieldsize)

Definition at line 173 of file Datum.cpp.

173  {
174  return ~minValue<T>(fieldsize);
175 }
template<typename T >
T anonymous_namespace{Datum.cpp}::minValue ( unsigned const  fieldsize)

Definition at line 167 of file Datum.cpp.

References heavydb.dtypes::T.

167  {
168  static_assert(std::is_signed_v<T>);
169  return T(-1) << (fieldsize - 1);
170 }
template<typename T , typename U = long double>
T anonymous_namespace{Datum.cpp}::parseFloatAsInteger ( std::string_view  s,
SQLTypeInfo const &  ti 
)

Definition at line 187 of file Datum.cpp.

References SQLTypeInfo::get_type_name(), and heavydb.dtypes::T.

187  {
188  // Use stack memory if s is small enough before resorting to dynamic memory.
189  constexpr size_t bufsize = 64;
190  char c_str[bufsize];
191  std::string str;
192  char const* str_begin;
193  char* str_end;
194  if (s.size() < bufsize) {
195  s.copy(c_str, s.size());
196  c_str[s.size()] = '\0';
197  str_begin = c_str;
198  } else {
199  str = s;
200  str_begin = str.c_str();
201  }
202  U value = strtold(str_begin, &str_end);
203  if (str_begin == str_end) {
204  throw std::runtime_error("Unable to parse " + std::string(s) + " to " +
205  ti.get_type_name());
206  } else if (str_begin + s.size() != str_end) {
207  throw std::runtime_error(std::string("Unexpected character \"") + *str_end +
208  "\" encountered in " + ti.get_type_name() + " value " +
209  std::string(s));
210  }
211  value = std::round(value);
212  if (!std::isfinite(value)) {
213  throw std::runtime_error("Invalid conversion from \"" + std::string(s) + "\" to " +
214  ti.get_type_name());
215  } else if (value < static_cast<U>(std::numeric_limits<T>::min()) ||
216  static_cast<U>(std::numeric_limits<T>::max()) < value) {
217  throw std::runtime_error("Integer " + std::string(s) + " is out of range for " +
218  ti.get_type_name());
219  }
220  return static_cast<T>(value);
221 }

+ Here is the call graph for this function:

template<typename T >
T anonymous_namespace{Datum.cpp}::parseInteger ( std::string_view  s,
SQLTypeInfo const &  ti 
)

Definition at line 229 of file Datum.cpp.

References SQLTypeInfo::get_comp_param(), SQLTypeInfo::get_compression(), SQLTypeInfo::get_notnull(), SQLTypeInfo::get_type_name(), hasCommonSuffix(), kENCODING_FIXED, heavydb.dtypes::T, and toString().

229  {
230  T retval{0};
231  char const* const end = s.data() + s.size();
232  auto [ptr, error_code] = std::from_chars(s.data(), end, retval);
233  if (ptr != end) {
234  if (error_code != std::errc() || !hasCommonSuffix(ptr, end)) {
235  retval = parseFloatAsInteger<T>(s, ti);
236  }
237  } else if (error_code != std::errc()) {
238  if (error_code == std::errc::result_out_of_range) {
239  throw std::runtime_error("Integer " + std::string(s) + " is out of range for " +
240  ti.get_type_name());
241  }
242  throw std::runtime_error("Invalid conversion from \"" + std::string(s) + "\" to " +
243  ti.get_type_name());
244  }
245  // Bounds checking based on SQLTypeInfo.
246  unsigned const fieldsize =
247  ti.get_compression() == kENCODING_FIXED ? ti.get_comp_param() : 8 * sizeof(T);
248  if (fieldsize < 8 * sizeof(T)) {
249  if (maxValue<T>(fieldsize) < retval) {
250  throw std::runtime_error("Integer " + std::string(s) +
251  " exceeds maximum value for " + toString(ti, fieldsize));
252  } else if (ti.get_notnull()) {
253  if (retval < minValue<T>(fieldsize)) {
254  throw std::runtime_error("Integer " + std::string(s) +
255  " exceeds minimum value for " + toString(ti, fieldsize));
256  }
257  } else {
258  if (retval <= minValue<T>(fieldsize)) {
259  throw std::runtime_error("Integer " + std::string(s) +
260  " exceeds minimum value for nullable " +
261  toString(ti, fieldsize));
262  }
263  }
264  } else if (!ti.get_notnull() && retval == std::numeric_limits<T>::min()) {
265  throw std::runtime_error("Integer " + std::string(s) +
266  " exceeds minimum value for nullable " +
267  toString(ti, fieldsize));
268  }
269  return retval;
270 }
std::string toString(const ExecutorDeviceType &device_type)
bool hasCommonSuffix(char const *const ptr, char const *const end)
Definition: Datum.cpp:224

+ Here is the call graph for this function:

std::string anonymous_namespace{Datum.cpp}::toString ( SQLTypeInfo const &  ti,
unsigned const  fieldsize 
)

Definition at line 177 of file Datum.cpp.

References SQLTypeInfo::get_type_name(), and to_string().

177  {
178  return ti.get_type_name() + '(' + std::to_string(fieldsize) + ')';
179 }
std::string to_string(char const *&&v)

+ Here is the call graph for this function: