diff --git a/velox/functions/prestosql/types/JsonType.cpp b/velox/functions/prestosql/types/JsonType.cpp index 9defbf9c7c98..7b11b8f9eaa1 100644 --- a/velox/functions/prestosql/types/JsonType.cpp +++ b/velox/functions/prestosql/types/JsonType.cpp @@ -569,16 +569,28 @@ simdjson::simdjson_result fromString(const std::string_view& s) { template simdjson::error_code convertIfInRange(From x, exec::GenericWriter& writer) { static_assert(std::is_signed_v && std::is_signed_v); - static_assert(std::is_integral_v || !std::is_integral_v); - if constexpr (!std::is_same_v) { - constexpr From kMin = std::numeric_limits::lowest(); - constexpr From kMax = std::numeric_limits::max(); + if constexpr (std::is_integral_v == std::is_integral_v) { + if constexpr (sizeof(To) < sizeof(From)) { + constexpr From kMin = std::numeric_limits::lowest(); + constexpr From kMax = std::numeric_limits::max(); + if (!(kMin <= x && x <= kMax)) { + return simdjson::NUMBER_OUT_OF_RANGE; + } + } + writer.castTo() = x; + return simdjson::SUCCESS; + } else { + static_assert(std::is_integral_v && !std::is_integral_v); + // Upper/lower bound values that could be accurately represented in both + // int64_t and double types. Same values are used by + // folly::constexpr_clamp_cast. + constexpr double kMin = -9223372036854774784.0; + constexpr double kMax = 9223372036854774784.0; if (!(kMin <= x && x <= kMax)) { return simdjson::NUMBER_OUT_OF_RANGE; } + return convertIfInRange(x, writer); } - writer.castTo() = x; - return simdjson::SUCCESS; } template