mrhhsg commented on code in PR #63396:
URL: https://github.com/apache/doris/pull/63396#discussion_r3278277409
##########
be/src/util/jsonb_document.h:
##########
@@ -1004,6 +1007,184 @@ struct ArrayVal : public ContainerVal {
namespace jsonb_detail {
+struct JsonbScaledDecimal {
+ wide::Int256 value;
+ uint32_t scale;
+};
+
+inline bool is_numeric(const JsonbValue* value) {
+ return value->isInt() || value->isDouble() || value->isFloat() ||
value->isDecimal();
+}
+
+inline double floating_value(const JsonbValue* value) {
+ if (value->isDouble()) {
+ return value->unpack<JsonbDoubleVal>()->val();
+ }
+ return value->unpack<JsonbFloatVal>()->val();
+}
+
+inline JsonbScaledDecimal get_scaled_decimal(const JsonbValue* value) {
+ switch (value->type) {
+ case JsonbType::T_Decimal32: {
+ const auto* decimal = value->unpack<JsonbDecimal32>();
+ return {wide::Int256(decimal->val()), decimal->scale};
+ }
+ case JsonbType::T_Decimal64: {
+ const auto* decimal = value->unpack<JsonbDecimal64>();
+ return {wide::Int256(decimal->val()), decimal->scale};
+ }
+ case JsonbType::T_Decimal128: {
+ const auto* decimal = value->unpack<JsonbDecimal128>();
+ return {wide::Int256(decimal->val()), decimal->scale};
+ }
+ case JsonbType::T_Decimal256: {
+ const auto* decimal = value->unpack<JsonbDecimal256>();
+ return {decimal->val(), decimal->scale};
+ }
+ default:
+ throw Exception(ErrorCode::INTERNAL_ERROR, "Invalid JSONB decimal
value type: {}",
+ static_cast<int32_t>(value->type));
+ }
+}
+
+inline bool scaled_decimal_equal_decimal(const JsonbScaledDecimal& lhs,
+ const JsonbScaledDecimal& rhs) {
+ if (lhs.scale == rhs.scale) {
+ return lhs.value == rhs.value;
+ }
+
+ if (lhs.scale < rhs.scale) {
+ const auto scale_multiplier =
decimal_scale_multiplier<wide::Int256>(rhs.scale - lhs.scale);
+ return rhs.value % scale_multiplier == 0 && lhs.value == rhs.value /
scale_multiplier;
+ }
+
+ const auto scale_multiplier =
decimal_scale_multiplier<wide::Int256>(lhs.scale - rhs.scale);
+ return lhs.value % scale_multiplier == 0 && lhs.value / scale_multiplier
== rhs.value;
+}
+
+inline bool scaled_decimal_equal_integer(const JsonbScaledDecimal& decimal,
int128_t integer) {
+ const auto integer_value = wide::Int256(integer);
+ if (decimal.scale == 0) {
+ return decimal.value == integer_value;
+ }
+
+ const auto scale_multiplier =
decimal_scale_multiplier<wide::Int256>(decimal.scale);
+ return decimal.value % scale_multiplier == 0 &&
+ decimal.value / scale_multiplier == integer_value;
+}
+
+inline constexpr auto kPowersOfFive = [] {
+ std::array<wide::Int256, BeConsts::MAX_DECIMALV3_SCALE + 1> powers {};
+ powers[0] = 1;
+ for (size_t i = 1; i < powers.size(); ++i) {
+ powers[i] = powers[i - 1] * 5;
+ }
+ return powers;
+}();
+
+inline wide::Int256 power_of_five(uint32_t exponent) {
Review Comment:
Fixed in b32ca54d6ad. `power_of_five` now validates the scale on the release
path before indexing the lookup table, and decimal metadata is validated when
unpacking JSONB decimals. Added
`JsonbDocumentTest.contains_invalid_decimal_scale` to cover malformed scale
metadata compared with double in both directions.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]