256 lines
9.4 KiB
C++
256 lines
9.4 KiB
C++
/**
|
|
* Copyright (c) 2021 OceanBase
|
|
* OceanBase CE is licensed under Mulan PubL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
|
* You may obtain a copy of Mulan PubL v2 at:
|
|
* http://license.coscl.org.cn/MulanPubL-2.0
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PubL v2 for more details.
|
|
* This file is for define of expr lob utils
|
|
*/
|
|
|
|
#ifndef OCEANBASE_SQL_OB_EXPR_LOB_UTILS_H_
|
|
#define OCEANBASE_SQL_OB_EXPR_LOB_UTILS_H_
|
|
|
|
#include "share/ob_lob_access_utils.h"
|
|
#include "sql/engine/expr/ob_expr_util.h"
|
|
#include "sql/session/ob_sql_session_info.h"
|
|
|
|
namespace oceanbase
|
|
{
|
|
namespace sql
|
|
{
|
|
|
|
// wrapper class to handle sql expr string/text type result
|
|
class ObTextStringDatumResult : public common::ObTextStringResult
|
|
{
|
|
public:
|
|
ObTextStringDatumResult(const ObObjType type, const ObExpr* expr, ObEvalCtx *ctx, ObDatum *res_datum) :
|
|
common::ObTextStringResult(type, expr->obj_meta_.has_lob_header(), NULL), expr_(expr), ctx_(ctx), res_datum_(res_datum)
|
|
{}
|
|
ObTextStringDatumResult(const ObObjType type, bool has_header, ObDatum *res_datum) :
|
|
common::ObTextStringResult(type, has_header, NULL), expr_(NULL), ctx_(NULL), res_datum_(res_datum)
|
|
{}
|
|
|
|
~ObTextStringDatumResult(){};
|
|
|
|
TO_STRING_KV(KP_(expr), KP_(ctx), KPC_(res_datum));
|
|
|
|
int init(int64_t res_len, ObIAllocator *allocator = NULL);
|
|
int init_with_batch_idx(int64_t res_len, int64_t batch_idx);
|
|
void set_result();
|
|
|
|
private:
|
|
char * buff_alloc (const int64_t size);
|
|
|
|
private:
|
|
// for exprs
|
|
const ObExpr *expr_;
|
|
ObEvalCtx *ctx_;
|
|
ObDatum *res_datum_;
|
|
};
|
|
|
|
class ObTextStringObObjResult : public common::ObTextStringResult
|
|
{
|
|
public:
|
|
ObTextStringObObjResult(const ObObjType type, ObObjCastParams *params, ObObj *res_obj, bool has_header) :
|
|
common::ObTextStringResult(type, has_header, NULL), params_(params), res_obj_(res_obj)
|
|
{}
|
|
|
|
~ObTextStringObObjResult(){};
|
|
|
|
TO_STRING_KV(KP_(params), KP_(res_obj));
|
|
int init(int64_t res_len, ObIAllocator *allocator = NULL);
|
|
void set_result();
|
|
|
|
private:
|
|
char * buff_alloc (const int64_t size);
|
|
|
|
private:
|
|
ObObjCastParams *params_;
|
|
ObObj *res_obj_;
|
|
};
|
|
|
|
class ObTextStringHelper
|
|
{
|
|
public:
|
|
static const uint32_t DEAFULT_LOB_PREFIX_BYTE_LEN = 4000;
|
|
|
|
static int get_string(const ObExpr &expr, ObIAllocator &allocator, int64_t idx,
|
|
ObDatum *datum, ObString &str)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (datum == NULL) {
|
|
str.assign_ptr("", 0);
|
|
} else if (datum->is_null()) {
|
|
str.assign_ptr("", 0);
|
|
} else {
|
|
str = datum->get_string();
|
|
const ObDatumMeta &meta = expr.args_[idx]->datum_meta_;
|
|
bool has_lob_header = expr.args_[idx]->obj_meta_.has_lob_header();
|
|
if (OB_FAIL(ObTextStringHelper::read_real_string_data(allocator, *datum, meta, has_lob_header, str))) {
|
|
COMMON_LOG(WARN, "Lob: fail to get string.", K(ret), K(str));
|
|
}
|
|
}
|
|
return ret;
|
|
};
|
|
|
|
static int read_real_string_data(ObIAllocator &allocator, const ObDatum &datum, const ObDatumMeta &meta,
|
|
bool has_lob_header, ObString &str)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
str = datum.get_string();
|
|
if (datum.is_null()) {
|
|
str.reset();
|
|
} else if (is_lob_storage(meta.type_)) {
|
|
ObTextStringIter str_iter(meta.type_, meta.cs_type_, str, has_lob_header);
|
|
if (OB_FAIL(str_iter.init(0, NULL, &allocator))) {
|
|
COMMON_LOG(WARN, "Lob: str iter init failed ", K(ret), K(str_iter));
|
|
} else if (OB_FAIL(str_iter.get_full_data(str))) {
|
|
COMMON_LOG(WARN, "Lob: str iter get full data failed ", K(ret), K(str_iter));
|
|
}
|
|
}
|
|
return ret;
|
|
};
|
|
|
|
static int read_real_string_data(ObIAllocator *allocator, const common::ObObj &obj, ObString &str)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
const ObObjMeta& meta = obj.get_meta();
|
|
str = obj.get_string();
|
|
if (meta.is_null()) {
|
|
str.reset();
|
|
} else if (is_lob_storage(meta.get_type())) {
|
|
ObTextStringIter str_iter(meta.get_type(), meta.get_collation_type(), str, obj.has_lob_header());
|
|
if (OB_FAIL(str_iter.init(0, NULL, allocator))) {
|
|
COMMON_LOG(WARN, "Lob: init lob str iter failed ", K(ret), K(str_iter));
|
|
} else if (OB_FAIL(str_iter.get_full_data(str))) {
|
|
COMMON_LOG(WARN, "Lob: str iter get full data failed ", K(ret), K(str_iter));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static int read_real_string_data(ObIAllocator *allocator, ObObjType type, ObCollationType cs_type,
|
|
bool has_lob_header, ObString &str)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (is_lob_storage(type)) {
|
|
ObTextStringIter str_iter(type, cs_type, str, has_lob_header);
|
|
if (OB_FAIL(str_iter.init(0, NULL, allocator))) {
|
|
COMMON_LOG(WARN, "Lob: init lob str iter failed ", K(ret), K(str_iter));
|
|
} else if (OB_FAIL(str_iter.get_full_data(str))) {
|
|
COMMON_LOG(WARN, "Lob: str iter get full data failed ", K(ret), K(str_iter));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// get outrow lob prefix or inrow/string tc full data
|
|
static int read_prefix_string_data(ObEvalCtx &ctx,
|
|
const ObDatum &datum,
|
|
const ObDatumMeta &meta,
|
|
const bool has_lob_header,
|
|
ObIAllocator *allocator,
|
|
ObString &str,
|
|
uint32_t prefix_char_len = DEAFULT_LOB_PREFIX_BYTE_LEN)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
str = datum.get_string();
|
|
if (datum.is_null()) {
|
|
str.reset();
|
|
} else if (ob_is_text_tc(meta.type_)) {
|
|
ObTextStringIter str_iter(meta.type_, meta.cs_type_, str, has_lob_header);
|
|
if (OB_FAIL(str_iter.init(0, NULL, allocator))) {
|
|
COMMON_LOG(WARN, "Lob: init lob str iter failed ", K(ret), K(str_iter));
|
|
} else if (OB_FAIL(str_iter.get_inrow_or_outrow_prefix_data(str, prefix_char_len))) {
|
|
COMMON_LOG(WARN, "Lob: init lob str iter failed ", K(ret), K(str_iter));
|
|
}
|
|
}
|
|
return ret;
|
|
};
|
|
|
|
// get outrow lob prefix or inrow/string tc full data
|
|
static int read_prefix_string_data(ObIAllocator *allocator,
|
|
const common::ObObj &obj,
|
|
ObString &str,
|
|
uint32_t prefix_char_len = DEAFULT_LOB_PREFIX_BYTE_LEN)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
const ObObjMeta& meta = obj.get_meta();
|
|
str = obj.get_string();
|
|
if (meta.is_null()) {
|
|
str.reset();
|
|
} else if (ob_is_text_tc(meta.get_type())) {
|
|
ObTextStringIter str_iter(meta.get_type(), meta.get_collation_type(), str, obj.has_lob_header());
|
|
if (OB_FAIL(str_iter.init(0, NULL, allocator))) {
|
|
COMMON_LOG(WARN, "Lob: init lob str iter failed ", K(ret), K(str_iter));
|
|
} else if (OB_FAIL(str_iter.get_inrow_or_outrow_prefix_data(str, prefix_char_len))) {
|
|
COMMON_LOG(WARN, "Lob: init lob str iter failed ", K(ret), K(str_iter));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static int get_char_len(ObEvalCtx &ctx, const ObDatum & datum, const ObDatumMeta &meta,
|
|
const bool has_lob_header, int64_t &char_len)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (datum.is_null()) {
|
|
char_len = 0;
|
|
} else {
|
|
ObString str = datum.get_string();
|
|
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
|
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
|
|
ObTextStringIter str_iter(meta.type_, meta.cs_type_, str, has_lob_header);
|
|
if (OB_FAIL(str_iter.init(0, NULL, &temp_allocator))) {
|
|
COMMON_LOG(WARN, "Lob: init lob str iter failed ", K(ret), K(str_iter));
|
|
} else if (OB_FAIL(str_iter.get_char_len(char_len))) {
|
|
COMMON_LOG(WARN, "Lob: init lob str iter failed ", K(ret), K(str_iter));
|
|
}
|
|
}
|
|
return ret;
|
|
};
|
|
|
|
static int string_to_templob_result(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res, const ObString &str)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObTextStringDatumResult tmp_lob_res(expr.datum_meta_.type_, &expr, &ctx, &res);
|
|
if (OB_FAIL(tmp_lob_res.init(str.length()))) {
|
|
COMMON_LOG(WARN, "Lob: init lob result failed");
|
|
} else if (OB_FAIL(tmp_lob_res.append(str.ptr(), str.length()))) {
|
|
COMMON_LOG(WARN, "Lob: append lob result failed");
|
|
} else {
|
|
tmp_lob_res.set_result();
|
|
}
|
|
return ret;
|
|
};
|
|
|
|
};
|
|
|
|
int ob_adjust_lob_datum(const ObObj &origin_obj,
|
|
const common::ObObjMeta &obj_meta,
|
|
const ObObjDatumMapType &obj_datum_map_,
|
|
ObIAllocator &allocator, // can avoid allocator if no persist lobs call this function,
|
|
ObDatum &out_datum);
|
|
|
|
int ob_adjust_lob_datum(const ObObj &origin_obj,
|
|
const common::ObObjMeta &obj_meta,
|
|
ObIAllocator &allocator,
|
|
ObDatum &out_datum);
|
|
|
|
int ob_adjust_lob_datum(const ObObj &origin_obj,
|
|
const common::ObObjMeta &obj_meta,
|
|
ObIAllocator &allocator,
|
|
ObDatum *out_datum);
|
|
|
|
int ob_adjust_lob_datum(ObDatum &datum,
|
|
const common::ObObjMeta &in_obj_meta,
|
|
const common::ObObjMeta &out_obj_meta,
|
|
ObIAllocator &allocator);
|
|
|
|
} // sql
|
|
} // oceanbase
|
|
#endif // OCEANBASE_SQL_OB_EXPR_LOB_UTILS_H_
|