From 0a7f62580a461613dc28927a5286170ddaf3dbe3 Mon Sep 17 00:00:00 2001 From: qijiax Date: Wed, 3 Jul 2024 14:26:41 +0000 Subject: [PATCH] Adapt negative integer behavior of roaringbitmap to PG --- .../src/lib/roaringbitmap/ob_rb_utils.cpp | 17 +++++++++---- .../aggregate/ob_aggregate_processor.cpp | 24 ++++++++++++++++--- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/deps/oblib/src/lib/roaringbitmap/ob_rb_utils.cpp b/deps/oblib/src/lib/roaringbitmap/ob_rb_utils.cpp index 165f9f63ed..63c8e90ab7 100644 --- a/deps/oblib/src/lib/roaringbitmap/ob_rb_utils.cpp +++ b/deps/oblib/src/lib/roaringbitmap/ob_rb_utils.cpp @@ -531,9 +531,18 @@ int ObRbUtils::str_read_value_(const char *str, size_t len, char *&value_end, u int ret = OB_SUCCESS; int err = 0; if (*str == '-') { - int64_t get_int64 = ObCharset::strntoll(str, len, 10, &value_end, &err); + int64_t val_64 = ObCharset::strntoll(str, len, 10, &value_end, &err); if (err == 0) { - value = static_cast(get_int64); + if (val_64 < INT32_MIN) { + ret = OB_SIZE_OVERFLOW; + LOG_WARN("negative integer not in the range of int32", K(ret), K(val_64)); + } else if (val_64 < 0) { + // convert negative integer to uint32 + uint32_t val_u32 = static_cast(val_64); + value = static_cast(val_u32); + } else { + value = static_cast(val_64); + } } else if (err == ERANGE) { ret = OB_SIZE_OVERFLOW; LOG_WARN("int64 value out of range", K(ret), K(str)); @@ -542,9 +551,9 @@ int ObRbUtils::str_read_value_(const char *str, size_t len, char *&value_end, u LOG_WARN("invalid int64 value", K(ret), K(str)); } } else { - uint64_t get_uint64 = ObCharset::strntoull(str, len, 10, &value_end, &err); + uint64_t val_u64 = ObCharset::strntoull(str, len, 10, &value_end, &err); if (err == 0) { - value = get_uint64; + value = val_u64; } else if (err == ERANGE) { ret = OB_SIZE_OVERFLOW; LOG_WARN("uint64 value out of range", K(ret), K(str)); diff --git a/src/sql/engine/aggregate/ob_aggregate_processor.cpp b/src/sql/engine/aggregate/ob_aggregate_processor.cpp index dcbb930a29..b5ec45b673 100644 --- a/src/sql/engine/aggregate/ob_aggregate_processor.cpp +++ b/src/sql/engine/aggregate/ob_aggregate_processor.cpp @@ -8424,6 +8424,8 @@ int ObAggregateProcessor::get_rb_build_agg_result(const ObAggrInfo &aggr_info, LOG_WARN("get unexpected null", K(ret), K(storted_row)); } else { // get obj + uint64_t val = 0; + bool null_val = false; if (!inited_tmp_obj && OB_ISNULL(tmp_obj = static_cast(tmp_alloc.alloc(sizeof(ObObj) * (storted_row->cnt_))))) { ret = OB_ALLOCATE_MEMORY_FAILED; @@ -8432,14 +8434,30 @@ int ObAggregateProcessor::get_rb_build_agg_result(const ObAggrInfo &aggr_info, } else if (OB_FAIL(convert_datum_to_obj(aggr_info, *storted_row, tmp_obj, storted_row->cnt_))) { LOG_WARN("failed to convert datum to obj", K(ret)); } else if (tmp_obj->is_null()) { - // do noting for null - } else if (!tmp_obj->is_integer_type()) { + null_val = true; + } else if (tmp_obj->is_unsigned_integer()) { + val = tmp_obj->get_uint64(); + } else if (tmp_obj->is_signed_integer()) { + int64_t val_64 = tmp_obj->get_int(); + if (val_64 < INT32_MIN) { + ret = OB_SIZE_OVERFLOW; + LOG_WARN("negative integer not in the range of int32", K(ret), K(val_64)); + } else if (val_64 < 0) { + // convert negative integer to uint32 + uint32_t val_u32 = static_cast(val_64); + val = static_cast(val_u32); + } else { + val = static_cast(val_64); + } + } else { ret = OB_ERR_INVALID_TYPE_FOR_ARGUMENT; LOG_WARN("invalid data type for roaringbitmap build agg"); + } + if (OB_FAIL(ret) || null_val) { } else if (OB_ISNULL(rb) && OB_ISNULL(rb = OB_NEWx(ObRoaringBitmap, &tmp_alloc, (&tmp_alloc)))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("failed to create alloc memory to roaringbitmap", K(ret)); - } else if (OB_FAIL(rb->value_add(tmp_obj->get_uint64()))) { + } else if (OB_FAIL(rb->value_add(val))) { LOG_WARN("failed to add value to roaringbitmap", K(ret), K(tmp_obj->get_uint64())); } }