59 "INTERVAL_YEAR_MONTH",
77 {
"NONE",
"FIXED",
"RL",
"DIFF",
"DICT",
"SPARSE",
"COMPRESSED",
"DAYS"};
84 constexpr
auto pow10 = shared::powersOf<uint64_t, max_scale + 1>(10);
86 if (dscale < -max_scale) {
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) {
98 return decimal_value * pow10[dscale];
100 if (!__builtin_mul_overflow(decimal_value, pow10[dscale], &retval)) {
105 if (decimal_value == 0) {
108 throw std::runtime_error(
"Overflow in DECIMAL-to-DECIMAL conversion.");
119 size_t dot = s.find_first_of(
'.', 0);
120 std::string before_dot;
121 std::string after_dot;
122 if (dot != std::string::npos) {
124 before_dot = (0 == dot) ?
"0" : s.substr(0, dot);
125 after_dot = s.substr(dot + 1);
130 const bool is_negative = before_dot.find_first_of(
'-', 0) != std::string::npos;
131 const int64_t sign = is_negative ? -1 : 1;
133 result = std::abs(std::stoll(before_dot));
134 int64_t fraction = 0;
135 const size_t before_dot_digits = before_dot.length() - (is_negative ? 1 : 0);
137 constexpr
int max_digits = std::numeric_limits<int64_t>::digits10;
138 if (!after_dot.empty()) {
139 int64_t next_digit = 0;
141 if (after_dot.size() + before_dot_digits > max_digits) {
142 if (before_dot_digits >= max_digits) {
145 next_digit = std::stoll(after_dot.substr(max_digits - before_dot_digits, 1));
146 after_dot = after_dot.substr(0, max_digits - before_dot_digits);
149 fraction = std::stoll(after_dot);
150 fraction += next_digit >= 5 ? 1 : 0;
154 ti.
set_scale(static_cast<int>(after_dot.length()));
162 return result * sign;
168 template <
typename T>
170 static_assert(std::is_signed_v<T>);
171 return T(-1) << (fieldsize - 1);
174 template <
typename T>
176 return ~minValue<T>(fieldsize);
188 template <
typename T,
typename U =
long double>
191 constexpr
size_t bufsize = 64;
194 char const* str_begin;
196 if (s.size() < bufsize) {
197 s.copy(c_str, s.size());
198 c_str[s.size()] =
'\0';
202 str_begin = str.c_str();
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 " +
208 }
else if (str_begin + s.size() != str_end) {
209 throw std::runtime_error(std::string(
"Unexpected character \"") + *str_end +
213 value = std::round(value);
214 if (!std::isfinite(value)) {
215 throw std::runtime_error(
"Invalid conversion from \"" + std::string(s) +
"\" to " +
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 " +
222 return static_cast<T>(value);
227 return *ptr ==
'.' && (ptr + 1 == end || (ptr[1] ==
'0' && ptr + 2 == end));
230 template <
typename T>
233 char const*
const end = s.data() + s.size();
234 auto [ptr,
error_code] = std::from_chars(s.data(), end, retval);
237 retval = parseFloatAsInteger<T>(s, ti);
240 if (
error_code == std::errc::result_out_of_range) {
241 throw std::runtime_error(
"Integer " + std::string(s) +
" is out of range for " +
244 throw std::runtime_error(
"Invalid conversion from \"" + std::string(s) +
"\" to " +
248 unsigned const fieldsize =
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));
255 if (retval < minValue<T>(fieldsize)) {
256 throw std::runtime_error(
"Integer " + std::string(s) +
257 " exceeds minimum value for " +
toString(ti, fieldsize));
260 if (retval <= minValue<T>(fieldsize)) {
261 throw std::runtime_error(
"Integer " + std::string(s) +
262 " exceeds minimum value for nullable " +
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 " +
324 throw std::runtime_error(
"Internal error: geometry type in NullDatum.");
326 throw std::runtime_error(
"Internal error: invalid type in NullDatum.");
348 if (s ==
"t" || s ==
"T" || s ==
"1" ||
to_upper(std::string(s)) ==
"TRUE") {
350 }
else if (s ==
"f" || s ==
"F" || s ==
"0" ||
351 to_upper(std::string(s)) ==
"FALSE") {
354 throw std::runtime_error(
"Invalid string for boolean " + std::string(s));
362 d.
bigintval = parseInteger<int64_t>(s, ti);
365 d.
intval = parseInteger<int32_t>(s, ti);
374 d.
floatval = std::stof(std::string(s));
394 throw std::runtime_error(
"Internal error: geometry type in StringToDatum.");
396 throw std::runtime_error(
"Internal error: invalid type in StringToDatum: " +
399 }
catch (
const std::invalid_argument&) {
400 throw std::runtime_error(
"Invalid conversion from string to " + ti.
get_type_name());
401 }
catch (
const std::out_of_range&) {
402 throw std::runtime_error(
"Got out of range error during conversion from string to " +
461 constexpr
size_t buf_size = 64;
497 CHECK_LE(19u +
bool(dim) + dim, len);
517 throw std::runtime_error(
"Internal error: invalid type " + ti.
get_type_name() +
518 " in DatumToString.");
590 return buf +
sizeof(int8_t);
595 return buf +
sizeof(int64_t);
597 *(int32_t*)buf = d.
intval;
598 return buf +
sizeof(int32_t);
601 return buf +
sizeof(int16_t);
604 return buf +
sizeof(int8_t);
607 return buf +
sizeof(
float);
610 return buf +
sizeof(
double);
614 *
reinterpret_cast<int64_t*
>(buf) = d.
bigintval;
615 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 Executor::ExtModuleKinds &kind)
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)