[CP] fix serialize ObSqlArrayObj bugs

This commit is contained in:
jingtaoye35
2024-01-02 13:13:05 +00:00
committed by ob-robot
parent 47aea9865a
commit bff45aaa70
10 changed files with 239 additions and 154 deletions

View File

@ -2320,8 +2320,8 @@ template <>
inline int obj_val_serialize<ObExtendType>(const ObObj &obj, char* buf, const int64_t buf_len, int64_t& pos)
{
int ret = OB_SUCCESS;
OB_UNIS_ENCODE(obj.get_ext());
if (obj.is_pl_extend()) {
OB_UNIS_ENCODE(obj.get_ext());
COMMON_LOG(ERROR, "Unexpected serialize", K(OB_NOT_SUPPORTED), K(obj), K(obj.get_meta().get_extend_type()));
return OB_NOT_SUPPORTED; //TODO:@ryan.ly: close this feature before composite refactor
if (NULL == serialize_composite_callback) {
@ -2329,6 +2329,18 @@ inline int obj_val_serialize<ObExtendType>(const ObObj &obj, char* buf, const in
} else {
ret = serialize_composite_callback(obj, buf, buf_len, pos);
}
} else if (obj.is_ext_sql_array()) {
int64_t v = 0;
OB_UNIS_ENCODE(v);
const ObSqlArrayObj *array_obj = reinterpret_cast<const ObSqlArrayObj*>(obj.get_ext());
if (OB_SUCC(ret) && NULL != array_obj) {
int64_t len = array_obj->get_serialize_size();
int64_t tmp_pos = pos;
OB_UNIS_ENCODE(len);
OB_UNIS_ENCODE(*array_obj);
}
} else {
OB_UNIS_ENCODE(obj.get_ext());
}
return ret;
}
@ -2347,6 +2359,20 @@ inline int obj_val_deserialize<ObExtendType>(ObObj &obj, const char* buf, const
} else {
ret = deserialize_composite_callback(obj, buf, data_len, pos);
}
} else if (obj.is_ext_sql_array()) {
if (OB_UNLIKELY(v != 0)) {
ret = OB_NOT_SUPPORTED;
COMMON_LOG(WARN, "using such type in upgrade period", K(ret));
} else {
int64_t len = 0;
int64_t tmp_pos = pos;
OB_UNIS_DECODE(len);
/* record the buffer and delay it's deserialize.
* should call ObSqlArrayObj::do_real_deserialize which need an allocator
*/
obj.set_extend(reinterpret_cast<int64_t>(buf + pos), T_EXT_SQL_ARRAY, int32_t(len));
pos += len;
}
} else {
obj.set_obj_value(v);
}
@ -2357,8 +2383,8 @@ template <>
inline int64_t obj_val_get_serialize_size<ObExtendType>(const ObObj &obj)
{
int64_t len = 0;
OB_UNIS_ADD_LEN(obj.get_ext());
if (obj.is_pl_extend()) {
OB_UNIS_ADD_LEN(obj.get_ext());
COMMON_LOG_RET(ERROR, OB_NOT_SUPPORTED, "Unexpected serialize", K(OB_NOT_SUPPORTED), K(obj), K(obj.get_meta().get_extend_type()));
return len; //TODO:@ryan.ly: close this feature before composite refactor
if (NULL == composite_serialize_size_callback) {
@ -2366,6 +2392,17 @@ inline int64_t obj_val_get_serialize_size<ObExtendType>(const ObObj &obj)
} else {
len += composite_serialize_size_callback(obj);
}
} else if (obj.is_ext_sql_array()) {
int64_t v = 0;
OB_UNIS_ADD_LEN(v);
const ObSqlArrayObj *array_obj = reinterpret_cast<const ObSqlArrayObj*>(obj.get_ext());
if (NULL != array_obj) {
int64_t array_obj_len = array_obj->get_serialize_size();
OB_UNIS_ADD_LEN(array_obj_len);
OB_UNIS_ADD_LEN(*array_obj);
}
} else {
OB_UNIS_ADD_LEN(obj.get_ext());
}
return len;
}

View File

@ -2227,35 +2227,6 @@ DEFINE_SERIALIZE(ObObjParam)
if (OB_SUCC(ret)) {
OB_UNIS_ENCODE(accuracy_);
OB_UNIS_ENCODE(res_flags_);
if (OB_SUCC(ret) && is_ext_sql_array()) {
const ObSqlArrayObj *array_obj = reinterpret_cast<const ObSqlArrayObj*>(get_ext());
int64_t n = sizeof(ObSqlArrayObj);
if (OB_ISNULL(array_obj)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected NULL ptr", K(ret), KP(array_obj));
} else if (buf_len - pos < n) {
ret = OB_BUF_NOT_ENOUGH;
LOG_WARN("serialize buf not enough", K(ret), "remain", buf_len - pos, "needed", n);
} else {
MEMCPY(buf + pos, array_obj, n);
pos += n;
if (array_obj->count_ == 0) {
/* do nothing */
} else if (OB_ISNULL(array_obj->data_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("data is NULL ptr", K(ret), KP(array_obj->data_));
} else {
n = sizeof(array_obj->data_[0]) * array_obj->count_;
if (buf_len - pos < n) {
ret = OB_BUF_NOT_ENOUGH;
LOG_WARN("serialize buf not enough", K(ret), "remain", buf_len - pos, "needed", n);
} else {
MEMCPY(buf + pos, static_cast<const void*>(array_obj->data_), n);
pos += n;
}
}
}
}
}
return ret;
}
@ -2266,30 +2237,6 @@ DEFINE_DESERIALIZE(ObObjParam)
if (OB_SUCC(ret)) {
OB_UNIS_DECODE(accuracy_);
OB_UNIS_DECODE(res_flags_);
if (OB_SUCC(ret) && is_ext_sql_array()) {
ObSqlArrayObj *array_obj = NULL;
int64_t n = sizeof(ObSqlArrayObj);
if (data_len - pos < n) {
ret = OB_BUF_NOT_ENOUGH;
LOG_WARN("deserialize buf not enough", K(ret), "remain", data_len - pos, "needed", n);
} else {
array_obj = reinterpret_cast<ObSqlArrayObj *>(const_cast<char *>(buf + pos));
pos += n;
}
if (OB_SUCC(ret) && array_obj->count_ > 0) {
n = sizeof(ObObjParam) * array_obj->count_;
if (data_len - pos < n) {
ret = OB_BUF_NOT_ENOUGH;
LOG_WARN("deserialize buf not enough", K(ret), "remain", data_len - pos, "needed", n);
} else {
array_obj->data_ = reinterpret_cast<ObObjParam *>(const_cast<char *>(buf + pos));
pos += n;
}
}
if (OB_SUCC(ret)) {
set_extend(reinterpret_cast<int64_t>(array_obj), T_EXT_SQL_ARRAY);
}
}
}
return ret;
}
@ -2299,18 +2246,6 @@ DEFINE_GET_SERIALIZE_SIZE(ObObjParam)
int64_t len = ObObj::get_serialize_size();
OB_UNIS_ADD_LEN(accuracy_);
OB_UNIS_ADD_LEN(res_flags_);
if (is_ext_sql_array()) {
len += sizeof(ObSqlArrayObj);
const ObSqlArrayObj *array_obj = reinterpret_cast<const ObSqlArrayObj*>(get_ext());
if (NULL != array_obj) {
len += sizeof(ObSqlArrayObj);
if (array_obj->count_ == 0) {
/* do nothing */
} else if (NULL != array_obj->data_) {
len += sizeof(array_obj->data_[0]) * array_obj->count_;
}
}
}
return len;
}
@ -2451,3 +2386,58 @@ int64_t ObHexEscapeSqlStr::get_extra_length() const
}
return ret_length;
}
int ObSqlArrayObj::do_real_deserialize(common::ObIAllocator &allocator, char *buf, int64_t data_len,
ObSqlArrayObj *&array_obj)
{
int ret = OB_SUCCESS;
int64_t n = sizeof(ObSqlArrayObj);
void *array_buf = allocator.alloc(n);
int64_t pos = 0;
if (OB_ISNULL(array_buf)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("allocate memory failed", K(ret));
} else {
array_obj = new (array_buf) ObSqlArrayObj();
if (OB_FAIL(array_obj->deserialize(allocator, buf, data_len, pos))) {
LOG_WARN("failed to deserialize ObSqlArrayObj", K(ret));
}
}
return ret;
}
DEFINE_SERIALIZE(ObSqlArrayObj)
{
int ret = OB_SUCCESS;
int64_t len = 0;
OB_UNIS_ENCODE(element_);
OB_UNIS_ENCODE_ARRAY(data_, count_);
return ret;
}
int ObSqlArrayObj::deserialize(ObIAllocator &allocator, const char* buf, const int64_t data_len,
int64_t& pos)
{
int ret = OB_SUCCESS;
OB_UNIS_DECODE(element_);
OB_UNIS_DECODE(count_);
if (OB_SUCC(ret) && count_ > 0) {
void *data_buf = allocator.alloc(sizeof(ObObjParam) * count_);
if (OB_ISNULL(data_buf)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("allocate memory failed", K(ret));
} else {
data_ = new (data_buf) common::ObObjParam[count_];
OB_UNIS_DECODE_ARRAY(data_, count_);
}
}
return ret;
}
DEFINE_GET_SERIALIZE_SIZE(ObSqlArrayObj)
{
int64_t len = 0;
OB_UNIS_ADD_LEN(element_);
OB_UNIS_ADD_LEN_ARRAY(data_, count_);
return len;
}

View File

@ -4150,6 +4150,10 @@ struct ObSqlArrayObj
}
typedef common::ObArrayWrap<common::ObObjParam> DataArray;
static ObSqlArrayObj *alloc(common::ObIAllocator &allocator, int64_t count);
static int do_real_deserialize(common::ObIAllocator &allocator, char *buf, int64_t data_len, ObSqlArrayObj *&array_obj);
int serialize(char* buf, const int64_t buf_len, int64_t& pos) const;
int deserialize(common::ObIAllocator &allocator, const char* buf, const int64_t data_len, int64_t& pos);
int64_t get_serialize_size(void) const;
TO_STRING_KV("data", DataArray(data_, count_), K_(count), K_(element));
common::ObObjParam *data_;
int64_t count_;