[FEAT MERGE] Lob SQL refactoring (Mem-LobLocator, expressions and dbms_lob adaptions)
Co-authored-by: chaser-ch <chaser.ch@antgroup.com>
This commit is contained in:
606
deps/oblib/src/common/object/ob_object.cpp
vendored
606
deps/oblib/src/common/object/ob_object.cpp
vendored
@ -258,6 +258,612 @@ DEF_TO_STRING(ObLobLocator)
|
||||
return pos;
|
||||
}
|
||||
|
||||
DEF_TO_STRING(ObLobLocatorV2)
|
||||
{
|
||||
int64_t pos = 0;
|
||||
uint32_t offset = 0;
|
||||
J_OBJ_START();
|
||||
J_KV(K_(ptr), K_(size), K_(has_lob_header));
|
||||
J_COMMA();
|
||||
|
||||
if (OB_ISNULL(ptr_)) {
|
||||
// do-nothing
|
||||
} else if (is_lob_disk_locator() && size_ >= sizeof(ObLobCommon)) {
|
||||
ObLobCommon *loc = reinterpret_cast<ObLobCommon *>(ptr_);
|
||||
J_KV(K(*loc));
|
||||
} else if (has_lob_header_ && size_ >= MEM_LOB_COMMON_HEADER_LEN) {
|
||||
ObMemLobCommon *loc = reinterpret_cast<ObMemLobCommon *>(ptr_);
|
||||
offset += MEM_LOB_COMMON_HEADER_LEN;
|
||||
J_KV(K(loc));
|
||||
J_COMMA();
|
||||
if (is_valid()) {
|
||||
if (buf_len > pos) {
|
||||
if (loc->has_extern()) {
|
||||
ObMemLobExternHeader *extern_header = reinterpret_cast<ObMemLobExternHeader *>(ptr_ + offset);
|
||||
offset += MEM_LOB_EXTERN_HEADER_LEN;
|
||||
J_KV(K(*extern_header));
|
||||
J_COMMA();
|
||||
J_KV("extern size", *(uint16_t *)extern_header->data_);
|
||||
J_COMMA();
|
||||
if (buf_len > pos && extern_header->flags_.has_tx_info_
|
||||
&& size_ >= offset + MEM_LOB_EXTERN_TXINFO_LEN) {
|
||||
ObMemLobTxInfo *tx_info = reinterpret_cast<ObMemLobTxInfo *>(ptr_ + offset);
|
||||
offset += MEM_LOB_EXTERN_TXINFO_LEN;
|
||||
J_KV(K(*tx_info));
|
||||
J_COMMA();
|
||||
}
|
||||
if (buf_len > pos && extern_header->flags_.has_location_info_
|
||||
&& size_ >= offset + MEM_LOB_EXTERN_LOCATIONINFO_LEN) {
|
||||
ObMemLobLocationInfo *location_info = reinterpret_cast<ObMemLobLocationInfo *>(ptr_ + offset);
|
||||
offset += MEM_LOB_EXTERN_LOCATIONINFO_LEN;
|
||||
J_KV(K(*location_info));
|
||||
J_COMMA();
|
||||
}
|
||||
if (buf_len > pos) {
|
||||
ObString rowkey_str(MIN(extern_header->rowkey_size_, buf_len - pos), ptr_ + offset);
|
||||
offset += extern_header->rowkey_size_;
|
||||
J_KV("rowkey", rowkey_str);
|
||||
J_COMMA();
|
||||
}
|
||||
if (buf_len > pos) {
|
||||
ObString payload_str(MIN(size_ - offset, buf_len - pos), ptr_ + offset);
|
||||
J_KV("disk locator", payload_str);
|
||||
}
|
||||
} else {
|
||||
ObString payload_str(MIN(size_ - offset, buf_len - pos), ptr_ + offset);
|
||||
J_KV("inrow data", payload_str);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ObString payload_str(MIN(size_ - offset, buf_len - pos), ptr_ + offset);
|
||||
J_KV("inrow", payload_str);
|
||||
}
|
||||
} else if (has_lob_header_ && size_ < MEM_LOB_COMMON_HEADER_LEN) {
|
||||
ObString payload_str(MIN(size_ - offset, buf_len - pos), ptr_ + offset);
|
||||
J_KV("content", payload_str);
|
||||
} else if (!has_lob_header_) {
|
||||
ObString payload_str(MIN(size_ - offset, buf_len - pos), ptr_ + offset);
|
||||
J_KV("compatable inrow data", payload_str);
|
||||
}
|
||||
|
||||
J_OBJ_END();
|
||||
return pos;
|
||||
}
|
||||
|
||||
// Notice: disk_lob_full_size = (disk locator header size if any) + inline buffer
|
||||
uint32_t ObLobLocatorV2::calc_locator_full_len(const ObMemLobExternFlags &flags,
|
||||
uint32_t rowkey_size,
|
||||
uint32_t disk_lob_full_size,
|
||||
bool is_simple)
|
||||
{
|
||||
uint32_t loc_len = MEM_LOB_COMMON_HEADER_LEN;
|
||||
if (!flags.is_empty()) {
|
||||
loc_len += MEM_LOB_EXTERN_HEADER_LEN;
|
||||
loc_len += MEM_LOB_EXTERN_SIZE_LEN;
|
||||
if (flags.has_tx_info_) {
|
||||
loc_len += MEM_LOB_EXTERN_TXINFO_LEN;
|
||||
}
|
||||
if (flags.has_location_info_) {
|
||||
loc_len += MEM_LOB_EXTERN_LOCATIONINFO_LEN;
|
||||
}
|
||||
loc_len += MEM_LOB_ADDR_LEN; //ToDo:@gehao server address.
|
||||
loc_len += rowkey_size;
|
||||
}
|
||||
if (is_simple) {
|
||||
loc_len += disk_lob_full_size;
|
||||
} else {
|
||||
loc_len += disk_lob_full_size;
|
||||
if (disk_lob_full_size != 0) {
|
||||
OB_ASSERT(disk_lob_full_size >= sizeof(ObLobCommon));
|
||||
} else {
|
||||
loc_len += sizeof(ObLobCommon);
|
||||
}
|
||||
}
|
||||
return loc_len;
|
||||
}
|
||||
|
||||
// fill mem header & rowkey
|
||||
int ObLobLocatorV2::fill(ObMemLobType type,
|
||||
const ObMemLobExternFlags &flags,
|
||||
const ObString &rowkey_str,
|
||||
const ObLobCommon *disk_loc,
|
||||
uint32_t disk_lob_full_size,
|
||||
bool is_simple)
|
||||
{
|
||||
validate_has_lob_header(has_lob_header_);
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(ptr_)
|
||||
|| (type <= INVALID_LOB || type >= MAX_LOB_TYPE)
|
||||
|| size_ < MEM_LOB_COMMON_HEADER_LEN) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
COMMON_LOG(WARN, "Lob: invalid argument",
|
||||
K(ret), K(type), KP(ptr_), K(size_), KP(disk_loc), K(disk_lob_full_size), K(is_simple));
|
||||
} else {
|
||||
uint32_t offset = 0;
|
||||
ObMemLobCommon *loc = new (ptr_ + offset) ObMemLobCommon(type, is_simple);
|
||||
loc->lob_common_.is_mem_loc_ = 1;
|
||||
loc->set_read_only(false);
|
||||
offset += MEM_LOB_COMMON_HEADER_LEN;
|
||||
if (flags.is_empty()) {
|
||||
// if no extern segment:
|
||||
// 1. simple case (only tinytext currently) only ObMemLobCommon and payload without disklocator
|
||||
// 2. not simple case:
|
||||
// 2.1 payload is empty, disk_lob_full_size should be 0, need to mock a disklocator
|
||||
// 2.2 payload is not empty, must has disklocator
|
||||
if (is_simple) {
|
||||
offset += disk_lob_full_size;
|
||||
} else if (disk_lob_full_size != 0) {
|
||||
offset += disk_lob_full_size;
|
||||
if (disk_lob_full_size < sizeof(ObLobCommon)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
COMMON_LOG(WARN, "Lob: invalid buffer size for disk locator",
|
||||
K(ret), K(type), K(disk_lob_full_size), K(sizeof(ObLobCommon)));
|
||||
}
|
||||
} else if (disk_lob_full_size == 0) {
|
||||
offset += sizeof(ObLobCommon);
|
||||
}
|
||||
} else {
|
||||
loc->set_extern(true);
|
||||
if (OB_UNLIKELY(offset + MEM_LOB_EXTERN_HEADER_LEN + MEM_LOB_EXTERN_SIZE_LEN > size_)) {
|
||||
ret = OB_BUF_NOT_ENOUGH;
|
||||
COMMON_LOG(WARN, "Lob: invalid buffer size for extern header",
|
||||
K(ret), K(type), KP(offset), K(size_));
|
||||
} else {
|
||||
ObMemLobExternHeader *extern_header =
|
||||
new (ptr_ + offset) ObMemLobExternHeader(flags, rowkey_str.length());
|
||||
offset += MEM_LOB_EXTERN_HEADER_LEN;
|
||||
|
||||
uint16_t *extern_len = reinterpret_cast<uint16_t *>(ptr_ + offset);
|
||||
offset += MEM_LOB_EXTERN_SIZE_LEN;
|
||||
*extern_len = 0;
|
||||
|
||||
if (flags.has_tx_info_) {
|
||||
offset += MEM_LOB_EXTERN_TXINFO_LEN;
|
||||
*extern_len += MEM_LOB_EXTERN_TXINFO_LEN;
|
||||
}
|
||||
if (flags.has_location_info_) {
|
||||
offset += MEM_LOB_EXTERN_LOCATIONINFO_LEN;
|
||||
*extern_len += MEM_LOB_EXTERN_LOCATIONINFO_LEN;
|
||||
}
|
||||
|
||||
if ((offset + rowkey_str.length()) && OB_UNLIKELY(offset > size_)) {
|
||||
ret = OB_BUF_NOT_ENOUGH;
|
||||
COMMON_LOG(WARN, "Lob: invalid buffer size for rowkey",
|
||||
K(ret), K(type), KP(offset), K(size_), K(flags), K(rowkey_str.length()));
|
||||
} else {
|
||||
MEMCPY(ptr_ + offset, rowkey_str.ptr(), rowkey_str.length());
|
||||
offset += rowkey_str.length();
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (disk_lob_full_size == 0) {
|
||||
extern_header->payload_offset_ = (offset - MEM_LOB_COMMON_HEADER_LEN - MEM_LOB_EXTERN_HEADER_LEN);
|
||||
extern_header->payload_size_ = 0;
|
||||
} else if (OB_ISNULL(disk_loc)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
COMMON_LOG(WARN, "Lob: building mem-loblocator has externs without disk locator",
|
||||
K(ret), K(type), KP(offset), K(size_), K(flags), K(rowkey_str.length()));
|
||||
} else if (disk_lob_full_size < sizeof(ObLobCommon)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
COMMON_LOG(WARN, "Lob: invalid buffer size for disk locator",
|
||||
K(ret), K(type), K(disk_lob_full_size), K(sizeof(ObLobCommon)));
|
||||
} else {
|
||||
uint32_t disk_loc_header_size = sizeof(ObLobCommon);
|
||||
if (disk_loc->is_init_) {
|
||||
disk_loc_header_size += sizeof(ObLobData);
|
||||
}
|
||||
if (offset + disk_loc_header_size > size_ || disk_lob_full_size < disk_loc_header_size) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
COMMON_LOG(WARN, "Lob: invalid disk locator",
|
||||
K(ret), K(type), KP(offset), K(size_), K(flags), K(offset),
|
||||
K(disk_loc_header_size), K(disk_lob_full_size), K(*disk_loc));
|
||||
} else {
|
||||
offset += disk_loc_header_size;
|
||||
// offset of disk locator inrow payload
|
||||
extern_header->payload_offset_ = (offset - MEM_LOB_COMMON_HEADER_LEN - MEM_LOB_EXTERN_HEADER_LEN);
|
||||
extern_header->payload_size_ = disk_lob_full_size - disk_loc_header_size; // size with lob full size
|
||||
offset += extern_header->payload_size_;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && OB_UNLIKELY(offset > size_)) {
|
||||
ret = OB_BUF_NOT_ENOUGH;
|
||||
COMMON_LOG(WARN, "Lob: invalid buffer size for disk data",
|
||||
K(ret), K(type), KP(offset), K(size_), K(flags), K(disk_lob_full_size));
|
||||
}
|
||||
}
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
int ObLobLocatorV2::copy(const ObLobLocatorV2* src_locator) const
|
||||
{
|
||||
return OB_NOT_IMPLEMENT;
|
||||
}
|
||||
|
||||
int ObLobLocatorV2:: get_mem_locator(ObMemLobCommon *&mem_loc) const
|
||||
{
|
||||
validate_has_lob_header(has_lob_header_);
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(!has_lob_header_)) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
} else if (is_lob_disk_locator()) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
} else {
|
||||
mem_loc = reinterpret_cast<ObMemLobCommon*>(ptr_);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLobLocatorV2::get_extern_header(ObMemLobExternHeader *&extern_header) const
|
||||
{
|
||||
validate_has_lob_header(has_lob_header_);
|
||||
int ret = OB_SUCCESS;
|
||||
ObMemLobCommon *loc = reinterpret_cast<ObMemLobCommon*>(ptr_);
|
||||
if (OB_UNLIKELY(!has_lob_header_)) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
} else if (is_lob_disk_locator()) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
} else if (!loc->has_extern()) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
} else {
|
||||
extern_header = reinterpret_cast<ObMemLobExternHeader *>(loc->data_);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLobLocatorV2::get_rowkey(ObString &rowkey_str) const
|
||||
{
|
||||
validate_has_lob_header(has_lob_header_);
|
||||
int ret = OB_SUCCESS;
|
||||
ObMemLobExternHeader *extern_header = NULL;
|
||||
if (OB_FAIL(get_extern_header(extern_header))) {
|
||||
} else {
|
||||
uint16_t extern_body_size = *((uint16_t *)(extern_header->data_));
|
||||
rowkey_str.assign(extern_header->data_ + MEM_LOB_EXTERN_SIZE_LEN + extern_body_size,
|
||||
extern_header->rowkey_size_);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLobLocatorV2::get_disk_locator(ObLobCommon *&disk_loc) const
|
||||
{
|
||||
validate_has_lob_header(has_lob_header_);
|
||||
int ret = OB_SUCCESS;
|
||||
ObMemLobCommon *loc = reinterpret_cast<ObMemLobCommon *>(ptr_);
|
||||
if (OB_UNLIKELY(!has_lob_header_)) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
COMMON_LOG(WARN, "Lob: try to get disk locator without lob header", K(ret));
|
||||
} else if (is_lob_disk_locator()) {
|
||||
disk_loc = reinterpret_cast<ObLobCommon *>(ptr_);
|
||||
} else if (loc->is_simple()) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
COMMON_LOG(WARN, "Lob: simple lob locator does not has disk locator", K(ret));
|
||||
} else if (loc->has_extern()) {
|
||||
ObString rowkey_str;
|
||||
if (OB_FAIL(get_rowkey(rowkey_str))) {
|
||||
COMMON_LOG(WARN, "Lob: get rowkey failed", K(ret));
|
||||
} else {
|
||||
disk_loc = reinterpret_cast<ObLobCommon *>(rowkey_str.ptr() + rowkey_str.length());
|
||||
}
|
||||
} else { // not simple, no extern
|
||||
disk_loc = reinterpret_cast<ObLobCommon *>(loc->data_);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLobLocatorV2::get_disk_locator(ObString &disc_loc_buff) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObLobCommon *disk_loc = NULL;
|
||||
if (OB_FAIL(get_disk_locator(disk_loc))) {
|
||||
COMMON_LOG(WARN, "Lob: get disk locator failed", K(ret));
|
||||
} else {
|
||||
int64_t handle_size = reinterpret_cast<intptr_t>(disk_loc) - reinterpret_cast<intptr_t>(ptr_);
|
||||
handle_size = size_ - handle_size;
|
||||
disc_loc_buff.assign_ptr(reinterpret_cast<const char *>(disk_loc), handle_size);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLobLocatorV2::get_inrow_data(ObString &inrow_data) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObString disk_loc_buff;
|
||||
ObMemLobCommon *loc = reinterpret_cast<ObMemLobCommon *>(ptr_);
|
||||
if (!has_lob_header_) {
|
||||
inrow_data.assign_ptr(ptr_, size_);
|
||||
} else if (!is_lob_disk_locator() && loc->is_simple()) {
|
||||
inrow_data.assign_ptr(ptr_ + MEM_LOB_COMMON_HEADER_LEN, size_ - MEM_LOB_COMMON_HEADER_LEN);
|
||||
} else if (OB_FAIL(get_disk_locator(disk_loc_buff))) {
|
||||
COMMON_LOG(WARN, "Lob: get disk locator failed", K(ret));
|
||||
} else {
|
||||
ObLobCommon *disk_loc = reinterpret_cast<ObLobCommon *>(disk_loc_buff.ptr());
|
||||
if (disk_loc->in_row_) {
|
||||
if (!is_lob_disk_locator() && !loc->has_inrow_data()) { // never disk locator inrow, but mem locator outrow
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
COMMON_LOG(WARN, "Lob: invalid outrow data", K(ret));
|
||||
} else {
|
||||
inrow_data.assign_ptr(disk_loc->get_inrow_data_ptr(), disk_loc->get_byte_size(disk_loc_buff.length()));
|
||||
}
|
||||
} else { // out row
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
COMMON_LOG(WARN, "Lob: Maybe a bug, get inrow data of outrow lob", K(ret), K(lbt()));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && inrow_data.length() == 0 && lib::is_oracle_mode()) {
|
||||
// Compatible with null string without header (old impliemnt of orale empty lob)
|
||||
// refer to mysqltest regula_expression_sqlqa.regular_replace_mysql
|
||||
inrow_data.assign_ptr(NULL, 0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ObLobLocatorV2::is_inrow() const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool bret = false;
|
||||
ObString disk_loc_buff;
|
||||
ObMemLobCommon *loc = reinterpret_cast<ObMemLobCommon *>(ptr_);
|
||||
if (!has_lob_header_) {
|
||||
bret = true;
|
||||
} else if (!is_lob_disk_locator() && loc->is_simple()) {
|
||||
bret = true;
|
||||
} else if (OB_FAIL(get_disk_locator(disk_loc_buff))) {
|
||||
COMMON_LOG(WARN, "Lob: get disk locator failed", K(ret));
|
||||
} else {
|
||||
ObLobCommon *disk_loc = reinterpret_cast<ObLobCommon *>(disk_loc_buff.ptr());
|
||||
bret = disk_loc->in_row_;
|
||||
}
|
||||
return bret;
|
||||
}
|
||||
|
||||
bool ObLobLocatorV2::is_empty_lob() const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool bret = false;
|
||||
ObString disk_loc_buff;
|
||||
ObMemLobCommon *loc = reinterpret_cast<ObMemLobCommon *>(ptr_);
|
||||
if (!has_lob_header_) {
|
||||
bret = (ptr_ == NULL && size_ == 0);
|
||||
} else if (!is_lob_disk_locator() && loc->is_simple()) {
|
||||
bret = (size_ - MEM_LOB_COMMON_HEADER_LEN == 0);
|
||||
} else if (OB_FAIL(get_disk_locator(disk_loc_buff))) {
|
||||
COMMON_LOG(WARN, "Lob: get disk locator failed", K(ret));
|
||||
} else {
|
||||
ObLobCommon *disk_loc = reinterpret_cast<ObLobCommon *>(disk_loc_buff.ptr());
|
||||
if (disk_loc->in_row_) {
|
||||
bret = (disk_loc->get_byte_size(disk_loc_buff.length()) == 0);
|
||||
}
|
||||
}
|
||||
return (ret == OB_SUCCESS ? bret : false);
|
||||
}
|
||||
|
||||
int ObLobLocatorV2::get_lob_data_byte_len(int64_t &len) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObString disk_loc_buff;
|
||||
ObMemLobCommon *loc = reinterpret_cast<ObMemLobCommon *>(ptr_);
|
||||
if (!has_lob_header_) {
|
||||
len = size_;
|
||||
} else if (!is_lob_disk_locator() && loc->is_simple()) {
|
||||
len = size_ - MEM_LOB_COMMON_HEADER_LEN;
|
||||
} else if (OB_FAIL(get_disk_locator(disk_loc_buff))) {
|
||||
COMMON_LOG(WARN, "Lob: get disk locator failed", K(ret));
|
||||
} else {
|
||||
ObLobCommon *disk_loc = reinterpret_cast<ObLobCommon *>(disk_loc_buff.ptr());
|
||||
len = disk_loc->get_byte_size(disk_loc_buff.length());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLobLocatorV2::get_table_info(uint64_t &table_id, uint32_t &column_idx)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObMemLobExternHeader *extern_header = NULL;
|
||||
if (OB_SUCC(get_extern_header(extern_header))) {
|
||||
table_id = extern_header->table_id_;
|
||||
column_idx = extern_header->column_idx_;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLobLocatorV2::get_tx_info(ObMemLobTxInfo *&tx_info) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObMemLobExternHeader *extern_header = NULL;
|
||||
if (OB_SUCC(get_extern_header(extern_header))) {
|
||||
if (extern_header->flags_.has_tx_info_) {
|
||||
tx_info = reinterpret_cast<ObMemLobTxInfo *>(extern_header->data_ + MEM_LOB_EXTERN_SIZE_LEN);
|
||||
} else {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
COMMON_LOG(WARN, "Lob: does not have tx info", K(this), K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLobLocatorV2::get_location_info(ObMemLobLocationInfo *&location_info) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObMemLobExternHeader *extern_header = NULL;
|
||||
if (OB_SUCC(get_extern_header(extern_header))) {
|
||||
char *cur_pos = extern_header->data_ + MEM_LOB_EXTERN_SIZE_LEN;
|
||||
if (extern_header->flags_.has_tx_info_) {
|
||||
cur_pos += MEM_LOB_EXTERN_TXINFO_LEN;
|
||||
}
|
||||
if (extern_header->flags_.has_location_info_) {
|
||||
location_info = reinterpret_cast<ObMemLobLocationInfo *>(cur_pos);
|
||||
} else {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
COMMON_LOG(WARN, "Lob: does not have location info", K(this), K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLobLocatorV2::get_real_locator_len(int64_t &real_len) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObLobCommon *disk_loc = NULL;
|
||||
ObMemLobCommon *loc = reinterpret_cast<ObMemLobCommon *>(ptr_);
|
||||
real_len = size_;
|
||||
if (!has_lob_header_) {
|
||||
} else if (!is_lob_disk_locator() && loc->is_simple_) {
|
||||
} else if (OB_FAIL(get_disk_locator(disk_loc))) {
|
||||
COMMON_LOG(WARN, "Lob: get disk locator failed", K(ret), K(*this));
|
||||
} else {
|
||||
real_len = (uintptr_t)disk_loc - (uintptr_t)ptr_;
|
||||
real_len += sizeof(ObLobCommon);
|
||||
if (disk_loc->is_init_) {
|
||||
real_len += sizeof(ObLobData);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Notice: this payload is payload with disk locator if it exist
|
||||
int ObLobLocatorV2::set_payload_data(const ObString& payload)
|
||||
{
|
||||
OB_ASSERT(has_lob_header_); // only used in build_lob_locator_v2, must has lob header
|
||||
int ret = OB_SUCCESS;
|
||||
ObMemLobCommon *loc = reinterpret_cast<ObMemLobCommon *>(ptr_);
|
||||
OB_ASSERT(loc->lob_common_.is_mem_loc_ == 1);
|
||||
uint32_t buf_len = size_ - (loc->data_ - ptr_);
|
||||
if (!loc->has_extern()) {
|
||||
OB_ASSERT(payload.length() == buf_len); // debug
|
||||
MEMCPY(loc->data_, payload.ptr(), buf_len);
|
||||
} else {
|
||||
ObString disk_loc_buff;
|
||||
if (OB_SUCC(get_disk_locator(disk_loc_buff))) {
|
||||
OB_ASSERT(payload.length() == disk_loc_buff.length());
|
||||
MEMCPY(disk_loc_buff.ptr(), payload.ptr(), disk_loc_buff.length());
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLobLocatorV2::set_payload_data(const ObLobCommon *lob_comm, const ObString& payload)
|
||||
{
|
||||
OB_ASSERT(has_lob_header_); // only used for fill temp lob header or default value lob locater v2
|
||||
int ret = OB_SUCCESS;
|
||||
uint32_t buf_len = 0;
|
||||
ObMemLobCommon *loc = reinterpret_cast<ObMemLobCommon *>(ptr_);
|
||||
OB_ASSERT(loc->lob_common_.is_mem_loc_ == 1);
|
||||
if (loc->is_simple()) {
|
||||
buf_len = size_ - (loc->data_ - ptr_);
|
||||
OB_ASSERT(payload.length() <= buf_len);
|
||||
if (payload.length() > 0) {
|
||||
MEMCPY(loc->data_, payload.ptr(), buf_len);
|
||||
}
|
||||
} else {
|
||||
char *buf = NULL;
|
||||
ObString disk_loc_buff;
|
||||
if (loc->has_extern()) {
|
||||
if (OB_SUCC(get_disk_locator(disk_loc_buff))) {
|
||||
buf = disk_loc_buff.ptr();
|
||||
buf_len = disk_loc_buff.length();
|
||||
}
|
||||
} else if (!loc->has_extern()) {
|
||||
buf = loc->data_;
|
||||
buf_len = size_ - (loc->data_ - ptr_);
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
uint32 disk_lob_header_len = sizeof(ObLobCommon);
|
||||
disk_lob_header_len += lob_comm->is_init_ ? sizeof(ObLobData) : 0;
|
||||
OB_ASSERT(payload.length() + disk_lob_header_len <= buf_len);
|
||||
MEMCPY(buf, lob_comm, disk_lob_header_len);
|
||||
if (payload.length() > 0) {
|
||||
MEMCPY(buf + disk_lob_header_len, payload.ptr(), payload.length());
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLobLocatorV2::set_table_info(const uint64_t &table_id, const uint32_t &column_idx)
|
||||
{
|
||||
validate_has_lob_header(has_lob_header_);
|
||||
int ret = OB_SUCCESS;
|
||||
ObMemLobExternHeader *extern_header = NULL;
|
||||
if (OB_SUCC(get_extern_header(extern_header))) {
|
||||
extern_header->table_id_ = table_id;
|
||||
extern_header->column_idx_ = column_idx;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLobLocatorV2::set_tx_info(const ObMemLobTxInfo &tx_info)
|
||||
{
|
||||
validate_has_lob_header(has_lob_header_);
|
||||
int ret = OB_SUCCESS;
|
||||
ObMemLobTxInfo *tx_info_ptr = NULL;
|
||||
if (OB_SUCC(get_tx_info(tx_info_ptr))) {
|
||||
*tx_info_ptr = tx_info;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLobLocatorV2::set_location_info(const ObMemLobLocationInfo &location_info)
|
||||
{
|
||||
validate_has_lob_header(has_lob_header_);
|
||||
int ret = OB_SUCCESS;
|
||||
ObMemLobLocationInfo *loc_info_ptr = NULL;
|
||||
if (OB_SUCC(get_location_info(loc_info_ptr))) {
|
||||
*loc_info_ptr = location_info;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_SERIALIZE(ObLobLocatorV2)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t new_pos = pos;
|
||||
if (NULL == buf || pos < 0 || pos > buf_len) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
} else if (new_pos + size_ + sizeof(size_) + sizeof(has_lob_header_) > buf_len) {
|
||||
ret = OB_SERIALIZE_ERROR;
|
||||
} else {
|
||||
*reinterpret_cast<uint32_t*>(buf + new_pos) = size_;
|
||||
new_pos += sizeof(size_);
|
||||
*reinterpret_cast<bool*>(buf + new_pos) = has_lob_header_;
|
||||
new_pos += sizeof(has_lob_header_);
|
||||
MEMCPY(buf + new_pos, ptr_, size_);
|
||||
new_pos += size_;
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
pos = new_pos;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_DESERIALIZE(ObLobLocatorV2)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t new_pos = pos;
|
||||
if (NULL == buf || pos < 0 || pos > data_len) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
} else if (new_pos + size_ + sizeof(size_) + sizeof(has_lob_header_) > data_len) {
|
||||
ret = OB_DESERIALIZE_ERROR;
|
||||
} else {
|
||||
size_ = *reinterpret_cast<const uint32_t*>(buf + new_pos);
|
||||
new_pos += sizeof(size_);
|
||||
has_lob_header_ = *reinterpret_cast<const uint32_t*>(buf + new_pos);
|
||||
new_pos += sizeof(has_lob_header_);
|
||||
ptr_ = const_cast<char*>(buf + new_pos);
|
||||
new_pos += size_;
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
pos = new_pos;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_SERIALIZE_SIZE(ObLobLocatorV2)
|
||||
{
|
||||
return size_ + sizeof(size_) + sizeof(has_lob_header_);
|
||||
}
|
||||
|
||||
#define PRINT_META()
|
||||
//#define PRINT_META() BUF_PRINTO(obj.get_meta()); J_COLON();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user