OmniSciDB  471d68cefb
 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)
 

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

Referenced by convert_decimal_value_to_scale(), and parse_numeric().

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

+ Here is the caller graph for this function:

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

Definition at line 222 of file Datum.cpp.

Referenced by parseInteger().

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

+ Here is the caller graph for this function:

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

Definition at line 171 of file Datum.cpp.

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

Definition at line 165 of file Datum.cpp.

References omnisci.dtypes::T.

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

Definition at line 185 of file Datum.cpp.

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

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

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

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

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

+ Here is the call graph for this function:

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

Definition at line 175 of file Datum.cpp.

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

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

+ Here is the call graph for this function: