[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:
@ -20,6 +20,7 @@
|
||||
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "lib/worker.h"
|
||||
#include "sql/engine/expr/ob_expr_lob_utils.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -302,38 +303,22 @@ int ObExprBaseLRpad::calc_type(ObExprResType &type,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprBaseLRpad::padding(LRpadType type,
|
||||
const ObCollationType coll_type,
|
||||
const char *text,
|
||||
const int64_t &text_size,
|
||||
const char *pad,
|
||||
const int64_t &pad_size,
|
||||
const int64_t &prefix_size,
|
||||
const int64_t &repeat_count,
|
||||
const bool &pad_space, // for oracle
|
||||
ObIAllocator *allocator,
|
||||
char* &result,
|
||||
int64_t &size)
|
||||
int ObExprBaseLRpad::padding_inner(LRpadType type,
|
||||
const char *text,
|
||||
const int64_t &text_size,
|
||||
const char *pad,
|
||||
const int64_t &pad_size,
|
||||
const int64_t &prefix_size,
|
||||
const int64_t &repeat_count,
|
||||
const bool &pad_space,
|
||||
ObString &space_str,
|
||||
char* &result)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObString space_str = ObCharsetUtils::get_const_str(coll_type, ' ');
|
||||
// start pos
|
||||
char *text_start_pos = NULL;
|
||||
char *pad_start_pos = NULL;
|
||||
char *sp_start_pos = NULL;
|
||||
|
||||
size = text_size + pad_size * repeat_count + prefix_size + (pad_space? space_str.length(): 0);
|
||||
if (OB_UNLIKELY(size <= 0)
|
||||
|| OB_UNLIKELY(repeat_count < 0)
|
||||
|| OB_UNLIKELY(pad_size <= 0)
|
||||
|| OB_UNLIKELY(prefix_size >= pad_size)
|
||||
|| (OB_ISNULL(text) && text_size != 0)
|
||||
|| OB_ISNULL(pad)
|
||||
|| OB_ISNULL(allocator)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("Wrong param", K(ret), K(size), K(repeat_count), K(pad_size), K(prefix_size),
|
||||
K(text), K(text_size), K(pad), K(allocator));
|
||||
} else if (OB_ISNULL(result = static_cast<char *>(allocator->alloc(size)))) {
|
||||
if (OB_ISNULL(result)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("Failed to alloc", K(ret));
|
||||
} else if (type == LPAD_TYPE) {
|
||||
@ -372,6 +357,67 @@ int ObExprBaseLRpad::padding(LRpadType type,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprBaseLRpad::padding(LRpadType type,
|
||||
const ObCollationType coll_type,
|
||||
const char *text,
|
||||
const int64_t &text_size,
|
||||
const char *pad,
|
||||
const int64_t &pad_size,
|
||||
const int64_t &prefix_size,
|
||||
const int64_t &repeat_count,
|
||||
const bool &pad_space, // for oracle
|
||||
ObIAllocator *allocator,
|
||||
char* &result,
|
||||
int64_t &size,
|
||||
ObObjType res_type,
|
||||
bool has_lob_header)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObString space_str = ObCharsetUtils::get_const_str(coll_type, ' ');
|
||||
// start pos
|
||||
char *text_start_pos = NULL;
|
||||
char *pad_start_pos = NULL;
|
||||
char *sp_start_pos = NULL;
|
||||
|
||||
size = text_size + pad_size * repeat_count + prefix_size + (pad_space? space_str.length(): 0);
|
||||
if (OB_UNLIKELY(size <= 0)
|
||||
|| OB_UNLIKELY(repeat_count < 0)
|
||||
|| OB_UNLIKELY(pad_size <= 0)
|
||||
|| OB_UNLIKELY(prefix_size >= pad_size)
|
||||
|| (OB_ISNULL(text) && text_size != 0)
|
||||
|| OB_ISNULL(pad)
|
||||
|| OB_ISNULL(allocator)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("Wrong param", K(ret), K(size), K(repeat_count), K(pad_size), K(prefix_size),
|
||||
K(text), K(text_size), K(pad), K(allocator));
|
||||
} else {
|
||||
if (!ob_is_text_tc(res_type)) {
|
||||
result = static_cast<char *>(allocator->alloc(size));
|
||||
// result validation inside padding_inner
|
||||
ret = padding_inner(type, text, text_size, pad, pad_size, prefix_size,
|
||||
repeat_count, pad_space, space_str, result);
|
||||
} else { // res is text tc
|
||||
ObTextStringResult result_buffer(res_type, has_lob_header, allocator);
|
||||
int64_t buffer_len = 0;
|
||||
if (OB_FAIL(result_buffer.init(size))) {
|
||||
LOG_WARN("init stringtextbuffer failed", K(ret), K(size));
|
||||
} else if (OB_FAIL(result_buffer.get_reserved_buffer(result, buffer_len))) {
|
||||
LOG_WARN("get empty buffer len failed", K(ret), K(buffer_len));
|
||||
} else if (OB_FAIL(padding_inner(type, text, text_size, pad, pad_size, prefix_size,
|
||||
repeat_count, pad_space, space_str, result))) {
|
||||
} else if (OB_FAIL(result_buffer.lseek(buffer_len, 0))) {
|
||||
LOG_WARN("temp lob lseek failed", K(ret));
|
||||
} else {
|
||||
ObString output;
|
||||
result_buffer.get_result_buffer(output);
|
||||
result = output.ptr();
|
||||
size = output.length();
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprBaseLRpad::calc(const LRpadType type,
|
||||
const ObObj &text,
|
||||
const ObObj &len,
|
||||
@ -438,7 +484,7 @@ int ObExprBaseLRpad::calc_mysql(const LRpadType type,
|
||||
result.set_null();
|
||||
} else {
|
||||
TYPE_CHECK(len, ObIntType);
|
||||
|
||||
bool has_lob_header = result_type.has_lob_header();
|
||||
if (OB_FAIL(len.get_int(int_len))) {
|
||||
LOG_WARN("Failed to get len", K(ret), K(len));
|
||||
} else if (int_len < 0) {
|
||||
@ -446,10 +492,22 @@ int ObExprBaseLRpad::calc_mysql(const LRpadType type,
|
||||
} else if (int_len == 0) {
|
||||
result.set_varchar(ObString::make_empty_string());
|
||||
result.set_collation(result_type);
|
||||
} else if (OB_FAIL(text.get_string(str_text))) {
|
||||
LOG_WARN("Failed to get str_text", K(ret), K(text));
|
||||
} else if (OB_FAIL(pad_text.get_string(str_pad))) {
|
||||
LOG_WARN("Failed to get str_text", K(ret), K(pad_text));
|
||||
} else if (!ob_is_text_tc(text.get_type()) && !ob_is_text_tc(pad_text.get_type())) {
|
||||
if (OB_FAIL(text.get_string(str_text))) {
|
||||
LOG_WARN("Failed to get str_text", K(ret), K(text));
|
||||
} else if (OB_FAIL(pad_text.get_string(str_pad))) {
|
||||
LOG_WARN("Failed to get str_text", K(ret), K(pad_text));
|
||||
}
|
||||
} else { // text tc
|
||||
str_text = text.get_string();
|
||||
str_pad = pad_text.get_string();
|
||||
if (OB_FAIL(ObTextStringHelper::read_real_string_data(allocator, text, str_text))) {
|
||||
LOG_WARN("failed to read real text", K(ret), K(str_text));
|
||||
} else if (OB_FAIL(ObTextStringHelper::read_real_string_data(allocator, pad_text, str_pad))) {
|
||||
LOG_WARN("failed to read real pattern", K(ret), K(str_pad));
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (FALSE_IT(text_len = ObCharset::strlen_char(
|
||||
result_type.get_collation_type(),
|
||||
const_cast<const char *>(str_text.ptr()),
|
||||
@ -482,11 +540,15 @@ int ObExprBaseLRpad::calc_mysql(const LRpadType type,
|
||||
}
|
||||
} else if (OB_FAIL(padding(type, result_type.get_collation_type(),
|
||||
str_text.ptr(), str_text.length(), str_pad.ptr(), str_pad.length(),
|
||||
prefix_size, repeat_count, false, allocator, result_ptr, result_size))) {
|
||||
prefix_size, repeat_count, false, allocator, result_ptr, result_size,
|
||||
result_type.get_type(), has_lob_header))) {
|
||||
LOG_WARN("Failed to pad", K(ret), K(str_text), K(str_pad), K(prefix_size), K(repeat_count));
|
||||
} else {
|
||||
result.set_string(result_type.get_type(), result_ptr, static_cast<ObString::obstr_size_t>(result_size));
|
||||
result.set_collation(result_type);
|
||||
if (has_lob_header) {
|
||||
result.set_has_lob_header();
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -542,13 +604,16 @@ int ObExprBaseLRpad::calc_mysql_pad_expr(const ObExpr &expr, ObEvalCtx &ctx,
|
||||
LOG_WARN("arg cnt must be 3", K(ret), K(expr.arg_cnt_));
|
||||
} else if (OB_FAIL(expr.eval_param_value(ctx, text, len, pad_text))) {
|
||||
LOG_WARN("eval param value failed", K(ret));
|
||||
} else if (OB_ISNULL(text) || OB_ISNULL(len) || OB_ISNULL(pad_text)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected datum", K(ret), KP(text), KP(len), KP(pad_text));
|
||||
} else {
|
||||
const ObSQLSessionInfo *session = ctx.exec_ctx_.get_my_session();
|
||||
ObExprStrResAlloc res_alloc(expr, ctx); // make sure alloc() is called only once
|
||||
if (OB_ISNULL(session)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("session is NULL", K(ret));
|
||||
} else if (OB_FAIL(calc_mysql(pad_type, expr, *text, *len, *pad_text, *session,
|
||||
} else if (OB_FAIL(calc_mysql(pad_type, expr, ctx, *text, *len, *pad_text, *session,
|
||||
res_alloc, res))) {
|
||||
LOG_WARN("calc_mysql failed", K(ret));
|
||||
}
|
||||
@ -556,13 +621,16 @@ int ObExprBaseLRpad::calc_mysql_pad_expr(const ObExpr &expr, ObEvalCtx &ctx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprBaseLRpad::calc_mysql(const LRpadType pad_type, const ObExpr &expr, const ObDatum &text,
|
||||
const ObDatum &len, const ObDatum &pad_text,
|
||||
const ObSQLSessionInfo &session, ObIAllocator &res_alloc,
|
||||
ObDatum &res)
|
||||
int ObExprBaseLRpad::calc_mysql_inner(const LRpadType pad_type,
|
||||
const ObExpr &expr,
|
||||
const ObDatum &len,
|
||||
int64_t &max_result_size,
|
||||
const ObString &str_text,
|
||||
const ObString &str_pad,
|
||||
ObIAllocator &res_alloc,
|
||||
ObDatum &res)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t max_result_size = -1;
|
||||
int64_t repeat_count = 0;
|
||||
int64_t prefix_size = 0;
|
||||
int64_t text_len = 0;
|
||||
@ -570,7 +638,54 @@ int ObExprBaseLRpad::calc_mysql(const LRpadType pad_type, const ObExpr &expr, co
|
||||
char *result_ptr = NULL;
|
||||
int64_t result_size = 0;
|
||||
const ObCollationType cs_type = expr.datum_meta_.cs_type_;
|
||||
const ObObjType type = expr.datum_meta_.type_;
|
||||
bool has_lob_header = expr.obj_meta_.has_lob_header();
|
||||
int64_t int_len = len.get_int();
|
||||
if (int_len < 0) {
|
||||
res.set_null();
|
||||
} else if (int_len == 0) {
|
||||
res.set_string(ObString::make_empty_string());
|
||||
} else if (FALSE_IT(text_len = ObCharset::strlen_char(cs_type,
|
||||
const_cast<const char *>(str_text.ptr()), str_text.length()))) {
|
||||
LOG_WARN("Failed to get displayed length", K(ret), K(str_text));
|
||||
} else if (text_len >= int_len ) {
|
||||
// only substr needed
|
||||
result_size = ObCharset::charpos(cs_type, str_text.ptr(), str_text.length(), int_len);
|
||||
res.set_string(ObString(result_size, str_text.ptr()));
|
||||
} else if (str_pad.length() == 0) {
|
||||
res.set_null();
|
||||
} else if (OB_FAIL(get_padding_info_mysql(cs_type, str_text, int_len, str_pad,
|
||||
max_result_size, repeat_count, prefix_size, result_size))) {
|
||||
LOG_WARN("Failed to get padding info", K(ret), K(str_text), K(int_len),
|
||||
K(str_pad), K(max_result_size));
|
||||
} else if (result_size > max_result_size) {
|
||||
res.set_null();
|
||||
if (pad_type == RPAD_TYPE) {
|
||||
LOG_USER_WARN(OB_ERR_FUNC_RESULT_TOO_LARGE, "rpad", static_cast<int>(max_result_size));
|
||||
} else {
|
||||
LOG_USER_WARN(OB_ERR_FUNC_RESULT_TOO_LARGE, "lpad", static_cast<int>(max_result_size));
|
||||
}
|
||||
} else if (OB_FAIL(padding(pad_type, cs_type, str_text.ptr(), str_text.length(), str_pad.ptr(),
|
||||
str_pad.length(), prefix_size, repeat_count, false, &res_alloc,
|
||||
result_ptr, result_size, type, has_lob_header))) {
|
||||
LOG_WARN("Failed to pad", K(ret), K(str_text), K(str_pad), K(prefix_size), K(repeat_count));
|
||||
} else {
|
||||
if (NULL == result_ptr || 0 == result_size) {
|
||||
res.set_null();
|
||||
} else {
|
||||
res.set_string(result_ptr, result_size);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprBaseLRpad::calc_mysql(const LRpadType pad_type, const ObExpr &expr, ObEvalCtx &ctx,
|
||||
const ObDatum &text, const ObDatum &len, const ObDatum &pad_text,
|
||||
const ObSQLSessionInfo &session, ObIAllocator &res_alloc,
|
||||
ObDatum &res)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t max_result_size = -1;
|
||||
if (OB_FAIL(session.get_max_allowed_packet(max_result_size))) {
|
||||
if (OB_ENTRY_NOT_EXIST == ret) { // for compatibility with server before 1470
|
||||
ret = OB_SUCCESS;
|
||||
@ -584,42 +699,34 @@ int ObExprBaseLRpad::calc_mysql(const LRpadType pad_type, const ObExpr &expr, co
|
||||
} else if (text.is_null() || len.is_null() || pad_text.is_null()) {
|
||||
res.set_null();
|
||||
} else {
|
||||
int64_t int_len = len.get_int();
|
||||
const ObString &str_text = text.get_string();
|
||||
const ObString &str_pad = pad_text.get_string();
|
||||
if (int_len < 0) {
|
||||
res.set_null();
|
||||
} else if (int_len == 0) {
|
||||
res.set_string(ObString::make_empty_string());
|
||||
} else if (FALSE_IT(text_len = ObCharset::strlen_char(cs_type,
|
||||
const_cast<const char *>(str_text.ptr()), str_text.length()))) {
|
||||
LOG_WARN("Failed to get displayed length", K(ret), K(str_text));
|
||||
} else if (text_len >= int_len ) {
|
||||
// only substr needed
|
||||
result_size = ObCharset::charpos(cs_type, str_text.ptr(), str_text.length(), int_len);
|
||||
res.set_string(ObString(result_size, str_text.ptr()));
|
||||
} else if (str_pad.length() == 0) {
|
||||
res.set_null();
|
||||
} else if (OB_FAIL(get_padding_info_mysql(cs_type, str_text, int_len, str_pad,
|
||||
max_result_size, repeat_count, prefix_size, result_size))) {
|
||||
LOG_WARN("Failed to get padding info", K(ret), K(str_text), K(int_len),
|
||||
K(str_pad), K(max_result_size));
|
||||
} else if (result_size > max_result_size) {
|
||||
res.set_null();
|
||||
if (pad_type == RPAD_TYPE) {
|
||||
LOG_USER_WARN(OB_ERR_FUNC_RESULT_TOO_LARGE, "rpad", static_cast<int>(max_result_size));
|
||||
} else {
|
||||
LOG_USER_WARN(OB_ERR_FUNC_RESULT_TOO_LARGE, "lpad", static_cast<int>(max_result_size));
|
||||
if (!ob_is_text_tc(expr.args_[0]->datum_meta_.type_)
|
||||
&& !ob_is_text_tc(expr.args_[2]->datum_meta_.type_)) {
|
||||
const ObString &str_text = text.get_string();
|
||||
const ObString &str_pad = pad_text.get_string();
|
||||
if (OB_FAIL(calc_mysql_inner(pad_type, expr, len, max_result_size,
|
||||
str_text, str_pad, res_alloc, res))) {
|
||||
LOG_WARN("Failed to eval base lrpad", K(ret));
|
||||
}
|
||||
} else if (OB_FAIL(padding(pad_type, cs_type, str_text.ptr(), str_text.length(), str_pad.ptr(),
|
||||
str_pad.length(), prefix_size, repeat_count, false, &res_alloc,
|
||||
result_ptr, result_size))) {
|
||||
LOG_WARN("Failed to pad", K(ret), K(str_text), K(str_pad), K(prefix_size), K(repeat_count));
|
||||
} else {
|
||||
if (NULL == result_ptr || 0 == result_size) {
|
||||
res.set_null();
|
||||
} else {
|
||||
res.set_string(result_ptr, result_size);
|
||||
} else { // text tc
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
|
||||
ObString str_text;
|
||||
ObString str_pad;
|
||||
if (OB_FAIL(ObTextStringHelper::read_real_string_data(temp_allocator,
|
||||
text,
|
||||
expr.args_[0]->datum_meta_,
|
||||
expr.args_[0]->obj_meta_.has_lob_header(),
|
||||
str_text))) {
|
||||
LOG_WARN("failed to read lob data text", K(ret), K(text));
|
||||
} else if (OB_FAIL(ObTextStringHelper::read_real_string_data(temp_allocator,
|
||||
pad_text,
|
||||
expr.args_[2]->datum_meta_,
|
||||
expr.args_[2]->obj_meta_.has_lob_header(),
|
||||
str_pad))) {
|
||||
LOG_WARN("failed to read lob data pattern", K(ret), K(pad_text));
|
||||
} else if (OB_FAIL(calc_mysql_inner(pad_type, expr, len, max_result_size,
|
||||
str_text, str_pad, res_alloc, res))) {
|
||||
LOG_WARN("Failed to eval base lrpad", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -690,10 +797,23 @@ int ObExprBaseLRpad::calc_oracle(const LRpadType type,
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (width <= 0) {
|
||||
result.set_null();
|
||||
} else if (OB_FAIL(text.get_string(str_text))) {
|
||||
LOG_WARN("Failed to get str_text", K(ret), K(text));
|
||||
} else if (OB_FAIL(pad_text.get_string(str_pad))) {
|
||||
LOG_WARN("Failed to get str_text", K(ret), K(pad_text));
|
||||
} else if (!ob_is_text_tc(text.get_type()) && !ob_is_text_tc(pad_text.get_type())) {
|
||||
if (OB_FAIL(text.get_string(str_text))) {
|
||||
LOG_WARN("Failed to get str_text", K(ret), K(text));
|
||||
} else if (OB_FAIL(pad_text.get_string(str_pad))) {
|
||||
LOG_WARN("Failed to get str_text", K(ret), K(pad_text));
|
||||
}
|
||||
} else { // text tc
|
||||
str_text = text.get_string();
|
||||
str_pad = pad_text.get_string();
|
||||
if (OB_FAIL(ObTextStringHelper::read_real_string_data(allocator, text, str_text))) {
|
||||
LOG_WARN("failed to read real text", K(ret), K(str_text));
|
||||
} else if (OB_FAIL(ObTextStringHelper::read_real_string_data(allocator, pad_text, str_pad))) {
|
||||
LOG_WARN("failed to read real pattern", K(ret), K(str_pad));
|
||||
}
|
||||
}
|
||||
bool has_lob_header = result_type.has_lob_header();
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(ObCharset::display_len(result_type.get_collation_type(), str_text, text_width))) {
|
||||
LOG_WARN("Failed to get displayed length", K(ret), K(str_text));
|
||||
} else {
|
||||
@ -710,7 +830,8 @@ int ObExprBaseLRpad::calc_oracle(const LRpadType type,
|
||||
LOG_WARN("Failed to get max display width", K(ret));
|
||||
} else if (OB_FAIL(padding(type, result_type.get_collation_type(),
|
||||
"", 0, str_text.ptr(), str_text.length(),
|
||||
prefix_size, 0, (total_width != width), allocator, result_ptr, result_size))) {
|
||||
prefix_size, 0, (total_width != width), allocator, result_ptr,
|
||||
result_size, result_type.get_type(), has_lob_header))) {
|
||||
LOG_WARN("Failed to pad", K(ret), K(str_text), K(str_pad), K(prefix_size), K(repeat_count), K(pad_space));
|
||||
}
|
||||
} else if (OB_FAIL(get_padding_info_oracle(
|
||||
@ -719,13 +840,17 @@ int ObExprBaseLRpad::calc_oracle(const LRpadType type,
|
||||
LOG_WARN("Failed to get padding info", K(ret), K(str_text), K(width), K(str_pad), K(max_result_size));
|
||||
} else if (OB_FAIL(padding(type, result_type.get_collation_type(),
|
||||
str_text.ptr(), str_text.length(), str_pad.ptr(), str_pad.length(),
|
||||
prefix_size, repeat_count, pad_space, allocator, result_ptr, result_size))) {
|
||||
prefix_size, repeat_count, pad_space, allocator, result_ptr,
|
||||
result_size, result_type.get_type(), has_lob_header))) {
|
||||
LOG_WARN("Failed to pad", K(ret), K(str_text), K(str_pad), K(prefix_size), K(repeat_count), K(pad_space));
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
result.set_string(result_type.get_type(), result_ptr, static_cast<ObString::obstr_size_t>(result_size));
|
||||
result.set_collation(result_type);
|
||||
if (has_lob_header) {
|
||||
result.set_has_lob_header();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -799,12 +924,56 @@ int ObExprBaseLRpad::calc_oracle_pad_expr(const ObExpr &expr, ObEvalCtx &ctx,
|
||||
LOG_WARN("eval param failed", K(ret));
|
||||
} else {
|
||||
ObExprStrResAlloc res_alloc(expr, ctx);
|
||||
bool is_unchanged_clob = false;
|
||||
if (3 == expr.arg_cnt_) {
|
||||
if (OB_ISNULL(text) || OB_ISNULL(len) || OB_ISNULL(pad_text)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected datum", K(ret), KP(text), KP(len), KP(pad_text));
|
||||
} else if (OB_FAIL(calc_oracle(pad_type, expr, *text, *len, *pad_text, res_alloc, res))) {
|
||||
LOG_WARN("calc pad failed", K(ret));
|
||||
} else {
|
||||
if (!ob_is_text_tc(expr.args_[0]->datum_meta_.type_)
|
||||
&& !ob_is_text_tc(expr.args_[2]->datum_meta_.type_)) {
|
||||
if (OB_FAIL(calc_oracle(pad_type, expr, *text, *len, *pad_text, res_alloc, res,
|
||||
is_unchanged_clob))) {
|
||||
LOG_WARN("calc pad failed", K(ret));
|
||||
}
|
||||
} else { // text tc
|
||||
ObDatum text_inrow;
|
||||
text_inrow.set_datum(*text); // copy meta
|
||||
ObDatum pad_text_inrow;
|
||||
pad_text_inrow.set_datum(*pad_text);
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
|
||||
|
||||
if (!text->is_null()) {
|
||||
ObString text_data = text->get_string();
|
||||
if (OB_FAIL(ObTextStringHelper::read_real_string_data(temp_allocator, *text,
|
||||
expr.args_[0]->datum_meta_,
|
||||
expr.args_[0]->obj_meta_.has_lob_header(),
|
||||
text_data))) {
|
||||
LOG_WARN("failed to read real text", K(ret), K(text_data));
|
||||
} else {
|
||||
text_inrow.set_string(text_data); // Notice: lob header flag is removed!
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && !pad_text->is_null()) {
|
||||
ObString pad_data = pad_text->get_string();
|
||||
if (OB_FAIL(ObTextStringHelper::read_real_string_data(temp_allocator, *pad_text,
|
||||
expr.args_[2]->datum_meta_,
|
||||
expr.args_[2]->obj_meta_.has_lob_header(),
|
||||
pad_data))) {
|
||||
LOG_WARN("failed to read real pattern", K(ret), K(pad_data));
|
||||
} else {
|
||||
pad_text_inrow.set_string(pad_data);
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(calc_oracle(pad_type, expr, text_inrow, *len, pad_text_inrow,
|
||||
res_alloc, res, is_unchanged_clob))) {
|
||||
LOG_WARN("calc pad for text failed", K(ret));
|
||||
} else if (is_unchanged_clob) {
|
||||
res.set_string(text->get_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (2 == expr.arg_cnt_) {
|
||||
ObCollationType in_coll = ObCharset::get_system_collation();
|
||||
@ -825,8 +994,34 @@ int ObExprBaseLRpad::calc_oracle_pad_expr(const ObExpr &expr, ObEvalCtx &ctx,
|
||||
LOG_WARN("unexpected pad_str after convert collation", K(ret), K(pad_str));
|
||||
} else {
|
||||
tmp_pad_text.set_string(pad_str);
|
||||
if (OB_FAIL(calc_oracle(pad_type, expr, *text, *len, tmp_pad_text, res_alloc, res))) {
|
||||
LOG_WARN("calc pad failed", K(ret));
|
||||
if (!ob_is_text_tc(expr.args_[0]->datum_meta_.type_)) {
|
||||
if (OB_FAIL(calc_oracle(pad_type, expr, *text, *len, tmp_pad_text, res_alloc, res,
|
||||
is_unchanged_clob))) {
|
||||
LOG_WARN("calc pad failed", K(ret));
|
||||
}
|
||||
} else { // text tc
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
|
||||
ObDatum text_inrow;
|
||||
text_inrow.set_datum(*text);
|
||||
if (!text->is_null()) {
|
||||
ObString text_data = text->get_string();
|
||||
if (OB_FAIL(ObTextStringHelper::read_real_string_data(temp_allocator, *text,
|
||||
expr.args_[0]->datum_meta_,
|
||||
expr.args_[0]->obj_meta_.has_lob_header(),
|
||||
text_data))) {
|
||||
LOG_WARN("failed to read real text", K(ret), K(text_data));
|
||||
} else {
|
||||
text_inrow.set_string(text_data);
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(calc_oracle(pad_type, expr, text_inrow, *len, tmp_pad_text,
|
||||
res_alloc, res, is_unchanged_clob))) {
|
||||
LOG_WARN("calc pad failed", K(ret));
|
||||
} else if (is_unchanged_clob) {
|
||||
res.set_string(text->get_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -841,9 +1036,10 @@ int ObExprBaseLRpad::calc_oracle_pad_expr(const ObExpr &expr, ObEvalCtx &ctx,
|
||||
int ObExprBaseLRpad::calc_oracle(LRpadType pad_type, const ObExpr &expr,
|
||||
const ObDatum &text, const ObDatum &len,
|
||||
const ObDatum &pad_text, ObIAllocator &res_alloc,
|
||||
ObDatum &res)
|
||||
ObDatum &res, bool &is_unchanged_clob)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObObjType res_type = expr.datum_meta_.type_;
|
||||
if (text.is_null() || len.is_null() || pad_text.is_null()) {
|
||||
res.set_null();
|
||||
} else {
|
||||
@ -877,11 +1073,14 @@ int ObExprBaseLRpad::calc_oracle(LRpadType pad_type, const ObExpr &expr,
|
||||
&& (text_width <= width)) {
|
||||
// pad_text 是 empty_clob,text 是 clob,如果不走截断逻辑的话,结果直接置为原 clob
|
||||
res.set_datum(text);
|
||||
is_unchanged_clob = ob_is_text_tc(res_type);
|
||||
} else if (text_width == width) {
|
||||
res.set_datum(text);
|
||||
is_unchanged_clob = ob_is_text_tc(res_type);
|
||||
} else {
|
||||
char *result_ptr = NULL;
|
||||
int64_t result_size = 0;
|
||||
bool has_lob_header = expr.obj_meta_.has_lob_header();
|
||||
if (text_width > width) {
|
||||
// substr
|
||||
int64_t total_width = 0;
|
||||
@ -890,7 +1089,7 @@ int ObExprBaseLRpad::calc_oracle(LRpadType pad_type, const ObExpr &expr,
|
||||
LOG_WARN("Failed to get max display width", K(ret));
|
||||
} else if (OB_FAIL(padding(pad_type, cs_type, "", 0, str_text.ptr(), str_text.length(),
|
||||
prefix_size, 0, (total_width != width), &res_alloc,
|
||||
result_ptr, result_size))) {
|
||||
result_ptr, result_size, res_type, has_lob_header))) {
|
||||
LOG_WARN("Failed to pad", K(ret), K(str_text), K(str_pad), K(prefix_size),
|
||||
K(repeat_count), K(pad_space));
|
||||
}
|
||||
@ -900,7 +1099,7 @@ int ObExprBaseLRpad::calc_oracle(LRpadType pad_type, const ObExpr &expr,
|
||||
K(str_pad), K(max_result_size));
|
||||
} else if (OB_FAIL(padding(pad_type, cs_type, str_text.ptr(), str_text.length(), str_pad.ptr(),
|
||||
str_pad.length(), prefix_size, repeat_count, pad_space,
|
||||
&res_alloc, result_ptr, result_size))) {
|
||||
&res_alloc, result_ptr, result_size, res_type, has_lob_header))) {
|
||||
LOG_WARN("Failed to pad", K(ret), K(str_text), K(str_pad), K(prefix_size),
|
||||
K(repeat_count), K(pad_space));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user