59 "INTERVAL_YEAR_MONTH",
75 {
"NONE",
"FIXED",
"RL",
"DIFF",
"DICT",
"SPARSE",
"COMPRESSED",
"DAYS"};
82 constexpr
auto pow10 = shared::powersOf<uint64_t, max_scale + 1>(10);
84 if (dscale < -max_scale) {
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) {
96 return decimal_value * pow10[dscale];
98 if (!__builtin_mul_overflow(decimal_value, pow10[dscale], &retval)) {
103 if (decimal_value == 0) {
106 throw std::runtime_error(
"Overflow in DECIMAL-to-DECIMAL conversion.");
117 size_t dot = s.find_first_of(
'.', 0);
118 std::string before_dot;
119 std::string after_dot;
120 if (dot != std::string::npos) {
122 before_dot = (0 == dot) ?
"0" : s.substr(0, dot);
123 after_dot = s.substr(dot + 1);
128 const bool is_negative = before_dot.find_first_of(
'-', 0) != std::string::npos;
129 const int64_t sign = is_negative ? -1 : 1;
131 result = std::abs(std::stoll(before_dot));
132 int64_t fraction = 0;
133 const size_t before_dot_digits = before_dot.length() - (is_negative ? 1 : 0);
135 constexpr
int max_digits = std::numeric_limits<int64_t>::digits10;
136 if (!after_dot.empty()) {
137 int64_t next_digit = 0;
139 if (after_dot.size() + before_dot_digits > max_digits) {
140 if (before_dot_digits >= max_digits) {
143 next_digit = std::stoll(after_dot.substr(max_digits - before_dot_digits, 1));
144 after_dot = after_dot.substr(0, max_digits - before_dot_digits);
147 fraction = std::stoll(after_dot);
148 fraction += next_digit >= 5 ? 1 : 0;
152 ti.
set_scale(static_cast<int>(after_dot.length()));
160 return result * sign;
166 template <
typename T>
168 static_assert(std::is_signed_v<T>);
169 return T(-1) << (fieldsize - 1);
172 template <
typename T>
174 return ~minValue<T>(fieldsize);
186 template <
typename T,
typename U =
long double>
189 constexpr
size_t bufsize = 64;
192 char const* str_begin;
194 if (s.size() < bufsize) {
195 s.copy(c_str, s.size());
196 c_str[s.size()] =
'\0';
200 str_begin = str.c_str();
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 " +
206 }
else if (str_begin + s.size() != str_end) {
207 throw std::runtime_error(std::string(
"Unexpected character \"") + *str_end +
211 value = std::round(value);
212 if (!std::isfinite(value)) {
213 throw std::runtime_error(
"Invalid conversion from \"" + std::string(s) +
"\" to " +
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 " +
220 return static_cast<T>(value);
225 return *ptr ==
'.' && (ptr + 1 == end || (ptr[1] ==
'0' && ptr + 2 == end));
228 template <
typename T>
231 char const*
const end = s.data() + s.size();
232 auto [ptr, error_code] = std::from_chars(s.data(), end, retval);
235 retval = parseFloatAsInteger<T>(s, ti);
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 " +
242 throw std::runtime_error(
"Invalid conversion from \"" + std::string(s) +
"\" to " +
246 unsigned const fieldsize =
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));
253 if (retval < minValue<T>(fieldsize)) {
254 throw std::runtime_error(
"Integer " + std::string(s) +
255 " exceeds minimum value for " +
toString(ti, fieldsize));
258 if (retval <= minValue<T>(fieldsize)) {
259 throw std::runtime_error(
"Integer " + std::string(s) +
260 " exceeds minimum value for nullable " +
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 " +
322 throw std::runtime_error(
"Internal error: geometry type in NullDatum.");
324 throw std::runtime_error(
"Internal error: invalid type in NullDatum.");
346 if (s ==
"t" || s ==
"T" || s ==
"1" ||
to_upper(std::string(s)) ==
"TRUE") {
348 }
else if (s ==
"f" || s ==
"F" || s ==
"0" ||
349 to_upper(std::string(s)) ==
"FALSE") {
352 throw std::runtime_error(
"Invalid string for boolean " + std::string(s));
360 d.
bigintval = parseInteger<int64_t>(s, ti);
363 d.
intval = parseInteger<int32_t>(s, ti);
372 d.
floatval = std::stof(std::string(s));
392 throw std::runtime_error(
"Internal error: geometry type in StringToDatum.");
394 throw std::runtime_error(
"Internal error: invalid type in StringToDatum: " +
397 }
catch (
const std::invalid_argument&) {
398 throw std::runtime_error(
"Invalid conversion from string to " + ti.
get_type_name());
399 }
catch (
const std::out_of_range&) {
400 throw std::runtime_error(
"Got out of range error during conversion from string to " +
459 constexpr
size_t buf_size = 64;
495 CHECK_LE(19u +
bool(dim) + dim, len);
515 throw std::runtime_error(
"Internal error: invalid type " + ti.
get_type_name() +
516 " in DatumToString.");
588 return buf +
sizeof(int8_t);
593 return buf +
sizeof(int64_t);
595 *(int32_t*)buf = d.
intval;
596 return buf +
sizeof(int32_t);
599 return buf +
sizeof(int16_t);
602 return buf +
sizeof(int8_t);
605 return buf +
sizeof(
float);
608 return buf +
sizeof(
double);
612 *
reinterpret_cast<int64_t*
>(buf) = d.
bigintval;
613 return buf +
sizeof(int64_t);
static constexpr int32_t kMaxRepresentableNumericPrecision
HOST DEVICE int get_size() const
int8_t * append_datum(int8_t *buf, const Datum &d, const SQLTypeInfo &ti)
std::string DatumToString(Datum d, const SQLTypeInfo &ti)
T parseInteger(std::string_view s, SQLTypeInfo const &ti)
T maxValue(unsigned const fieldsize)
int64_t parse_numeric(const std::string_view s, SQLTypeInfo &ti)
HOST DEVICE int get_scale() const
Constants for Builtin SQL Types supported by HEAVY.AI.
HOST DEVICE SQLTypes get_type() const
size_t formatHMS(char *buf, size_t const max, int64_t const unixtime)
std::string to_string() const
T minValue(unsigned const fieldsize)
bool DatumEqual(const Datum a, const Datum b, const SQLTypeInfo &ti)
static std::string type_name[kSQLTYPE_LAST]
int64_t extract_int_type_from_datum(const Datum datum, const SQLTypeInfo &ti)
Datum StringToDatum(const std::string_view s, SQLTypeInfo &ti)
std::string toString(const ExecutorDeviceType &device_type)
bool IsNullDatum(const Datum datum, const SQLTypeInfo &ti)
Datum NullDatum(const SQLTypeInfo &ti)
SQLTypes decimal_to_int_type(const SQLTypeInfo &ti)
size_t formatDate(char *buf, size_t const max, int64_t const unixtime)
static std::string comp_name[kENCODING_LAST]
HOST DEVICE EncodingType get_compression() const
int64_t convert_decimal_value_to_scale(const int64_t decimal_value, const SQLTypeInfo &type_info, const SQLTypeInfo &new_type_info)
void set_dimension(int d)
SQLTypes get_int_type_by_size(size_t const nbytes)
HOST DEVICE int get_dimension() const
std::string get_type_name() const
size_t formatDateTime(char *buf, size_t const max, int64_t const timestamp, int const dimension, bool use_iso_format)
HOST DEVICE int get_comp_param() const
int64_t inline_fixed_encoding_null_val(const SQL_TYPE_INFO &ti)
int64_t convert_decimal_value_to_scale_internal(const int64_t decimal_value, int const dscale)
double extract_fp_type_from_datum(const Datum datum, const SQLTypeInfo &ti)
bool is_dict_encoded_string() const
bool hasCommonSuffix(char const *const ptr, char const *const end)
HOST DEVICE bool get_notnull() const
SQLTypes get_type_for_datum(const SQLTypeInfo &ti)
T parseFloatAsInteger(std::string_view s, SQLTypeInfo const &ti)
SQLTypes string_dict_to_int_type(const SQLTypeInfo &ti)