OmniSciDB  72c90bc290
 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 81 of file Datum.cpp.

References sql_constants::kMaxRepresentableNumericPrecision.

Referenced by convert_decimal_value_to_scale(), and parse_numeric().

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

+ Here is the caller graph for this function:

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

Definition at line 274 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.

274  {
275  SQLTypes type;
276  if (ti.is_decimal()) {
277  type = decimal_to_int_type(ti);
278  } else if (ti.is_dict_encoded_string()) {
279  type = string_dict_to_int_type(ti);
280  } else {
281  type = ti.get_type();
282  }
283  return type;
284 }
SQLTypes
Definition: sqltypes.h:65
HOST DEVICE SQLTypes get_type() const
Definition: sqltypes.h:391
SQLTypes decimal_to_int_type(const SQLTypeInfo &ti)
Definition: Datum.cpp:561
bool is_dict_encoded_string() const
Definition: sqltypes.h:641
bool is_decimal() const
Definition: sqltypes.h:568
SQLTypes string_dict_to_int_type(const SQLTypeInfo &ti)
Definition: Datum.cpp:565

+ 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 226 of file Datum.cpp.

Referenced by parseInteger().

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

+ Here is the caller graph for this function:

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

Definition at line 175 of file Datum.cpp.

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

Definition at line 169 of file Datum.cpp.

References heavydb.dtypes::T.

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

Definition at line 189 of file Datum.cpp.

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

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

+ 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 231 of file Datum.cpp.

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

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

+ Here is the call graph for this function:

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

Definition at line 179 of file Datum.cpp.

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

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

+ Here is the call graph for this function: