Fix regexp function type deduce bug
This commit is contained in:
@ -19,6 +19,7 @@
|
|||||||
#include "lib/charset/ob_charset.h"
|
#include "lib/charset/ob_charset.h"
|
||||||
#include "sql/engine/expr/ob_expr_regexp_context.h"
|
#include "sql/engine/expr/ob_expr_regexp_context.h"
|
||||||
#include "sql/engine/expr/ob_expr_util.h"
|
#include "sql/engine/expr/ob_expr_util.h"
|
||||||
|
#include "sql/resolver/expr/ob_raw_expr_util.h"
|
||||||
#include "sql/session/ob_sql_session_info.h"
|
#include "sql/session/ob_sql_session_info.h"
|
||||||
namespace oceanbase
|
namespace oceanbase
|
||||||
{
|
{
|
||||||
@ -845,25 +846,17 @@ int ObExprRegexContext::check_need_utf8(ObRawExpr *expr, bool &need_utf8)
|
|||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
need_utf8 = false;
|
need_utf8 = false;
|
||||||
if (OB_ISNULL(expr)) {
|
const ObRawExpr * real_expr = NULL;
|
||||||
|
if (OB_FAIL(ObRawExprUtils::get_real_expr_without_cast(expr, real_expr))) {
|
||||||
|
LOG_WARN("fail to get real expr without cast", K(ret));
|
||||||
|
} else if (OB_ISNULL(real_expr)) {
|
||||||
ret = OB_ERR_UNEXPECTED;
|
ret = OB_ERR_UNEXPECTED;
|
||||||
LOG_WARN("unexpected null expr", K(ret));
|
LOG_WARN("real expr is invalid", K(ret), K(real_expr));
|
||||||
} else if (T_FUN_SYS_CAST == expr->get_expr_type() &&
|
|
||||||
expr->has_flag(IS_INNER_ADDED_EXPR)) {
|
|
||||||
ObRawExpr * real_expr = expr->get_param_expr(0);
|
|
||||||
if (OB_ISNULL(real_expr)) {
|
|
||||||
ret = OB_ERR_UNEXPECTED;
|
|
||||||
LOG_WARN("unexpected null pattern", K(ret));
|
|
||||||
} else {
|
} else {
|
||||||
need_utf8 = real_expr->get_result_type().is_nchar() ||
|
need_utf8 = real_expr->get_result_type().is_nchar() ||
|
||||||
real_expr->get_result_type().is_nvarchar2() ||
|
real_expr->get_result_type().is_nvarchar2() ||
|
||||||
real_expr->get_result_type().is_blob();
|
real_expr->get_result_type().is_blob();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
need_utf8 = expr->get_result_type().is_nchar() ||
|
|
||||||
expr->get_result_type().is_nvarchar2() ||
|
|
||||||
expr->get_result_type().is_blob();
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#include "sql/engine/expr/ob_expr_regexp_count.h"
|
#include "sql/engine/expr/ob_expr_regexp_count.h"
|
||||||
#include "sql/engine/expr/ob_expr_operator.h"
|
#include "sql/engine/expr/ob_expr_operator.h"
|
||||||
#include "sql/engine/expr/ob_expr_lob_utils.h"
|
#include "sql/engine/expr/ob_expr_lob_utils.h"
|
||||||
|
#include "sql/resolver/expr/ob_raw_expr_util.h"
|
||||||
|
|
||||||
using namespace oceanbase::common;
|
using namespace oceanbase::common;
|
||||||
|
|
||||||
@ -48,6 +49,7 @@ int ObExprRegexpReplace::calc_result_typeN(ObExprResType &type,
|
|||||||
ObRawExpr * raw_expr = type_ctx.get_raw_expr();
|
ObRawExpr * raw_expr = type_ctx.get_raw_expr();
|
||||||
CK(NULL != type_ctx.get_raw_expr());
|
CK(NULL != type_ctx.get_raw_expr());
|
||||||
int64_t max_allowed_packet = 0;
|
int64_t max_allowed_packet = 0;
|
||||||
|
const ObRawExpr *real_expr = NULL;
|
||||||
if (OB_FAIL(ret)) {
|
if (OB_FAIL(ret)) {
|
||||||
} else if (OB_UNLIKELY(param_num < 2 || param_num > 6)) {
|
} else if (OB_UNLIKELY(param_num < 2 || param_num > 6)) {
|
||||||
ret = OB_ERR_PARAM_SIZE;
|
ret = OB_ERR_PARAM_SIZE;
|
||||||
@ -57,7 +59,13 @@ int ObExprRegexpReplace::calc_result_typeN(ObExprResType &type,
|
|||||||
LOG_WARN("get unexpected null", K(ret), K(type_ctx.get_session()));
|
LOG_WARN("get unexpected null", K(ret), K(type_ctx.get_session()));
|
||||||
} else if (OB_FAIL(type_ctx.get_session()->get_max_allowed_packet(max_allowed_packet))) {
|
} else if (OB_FAIL(type_ctx.get_session()->get_max_allowed_packet(max_allowed_packet))) {
|
||||||
LOG_WARN("failed to get max allowed packet", K(ret));
|
LOG_WARN("failed to get max allowed packet", K(ret));
|
||||||
|
} else if (OB_FAIL(ObRawExprUtils::get_real_expr_without_cast(raw_expr->get_param_expr(0), real_expr))) {
|
||||||
|
LOG_WARN("fail to get real expr without cast", K(ret));
|
||||||
|
} else if (OB_ISNULL(real_expr)) {
|
||||||
|
ret = OB_ERR_UNEXPECTED;
|
||||||
|
LOG_WARN("real expr is invalid", K(ret), K(real_expr));
|
||||||
} else {
|
} else {
|
||||||
|
const ObExprResType &text = real_expr->get_result_type();
|
||||||
for (int i = 0; OB_SUCC(ret) && i < param_num; i++) {
|
for (int i = 0; OB_SUCC(ret) && i < param_num; i++) {
|
||||||
if (!types[i].is_null() && !is_type_valid(types[i].get_type())) {
|
if (!types[i].is_null() && !is_type_valid(types[i].get_type())) {
|
||||||
ret = OB_INVALID_ARGUMENT;
|
ret = OB_INVALID_ARGUMENT;
|
||||||
@ -67,14 +75,13 @@ int ObExprRegexpReplace::calc_result_typeN(ObExprResType &type,
|
|||||||
if (OB_SUCC(ret)) {
|
if (OB_SUCC(ret)) {
|
||||||
if (lib::is_oracle_mode()) {
|
if (lib::is_oracle_mode()) {
|
||||||
//deduce length
|
//deduce length
|
||||||
ObExprResType &text = types[0];
|
|
||||||
int64_t to_len = types[2].get_length();
|
int64_t to_len = types[2].get_length();
|
||||||
common::ObLength len = text.get_length();
|
common::ObLength len = text.get_length();
|
||||||
int64_t offset = len * to_len;
|
int64_t offset = len * to_len;
|
||||||
len = static_cast<common::ObLength>(len + offset);
|
len = static_cast<common::ObLength>(len + offset);
|
||||||
CK(len <= INT32_MAX);
|
CK(len <= INT32_MAX);
|
||||||
type.set_length(static_cast<common::ObLength>(len));
|
type.set_length(static_cast<common::ObLength>(len));
|
||||||
auto input_params = make_const_carray(&types[0]);
|
auto input_params = make_const_carray(const_cast<ObExprResType*>(&text));
|
||||||
OZ(aggregate_string_type_and_charset_oracle(
|
OZ(aggregate_string_type_and_charset_oracle(
|
||||||
*type_ctx.get_session(), input_params, type, PREFER_VAR_LEN_CHAR));
|
*type_ctx.get_session(), input_params, type, PREFER_VAR_LEN_CHAR));
|
||||||
OZ(deduce_string_param_calc_type_and_charset(*type_ctx.get_session(), type, input_params));
|
OZ(deduce_string_param_calc_type_and_charset(*type_ctx.get_session(), type, input_params));
|
||||||
@ -83,15 +90,15 @@ int ObExprRegexpReplace::calc_result_typeN(ObExprResType &type,
|
|||||||
const common::ObLengthSemantics default_length_semantics = (OB_NOT_NULL(type_ctx.get_session())
|
const common::ObLengthSemantics default_length_semantics = (OB_NOT_NULL(type_ctx.get_session())
|
||||||
? type_ctx.get_session()->get_actual_nls_length_semantics()
|
? type_ctx.get_session()->get_actual_nls_length_semantics()
|
||||||
: common::LS_BYTE);
|
: common::LS_BYTE);
|
||||||
if (types[0].is_lob()) {
|
if (text.is_lob()) {
|
||||||
type.set_type(types[0].get_type());
|
type.set_type(text.get_type());
|
||||||
} else {
|
} else {
|
||||||
type.set_clob();
|
type.set_clob();
|
||||||
type.set_length_semantics(types[0].is_varchar_or_char() ? types[0].get_length_semantics() : default_length_semantics);
|
type.set_length_semantics(text.is_varchar_or_char() ? text.get_length_semantics() : default_length_semantics);
|
||||||
}
|
}
|
||||||
//建表列的最大长度
|
//建表列的最大长度
|
||||||
type.set_length(max_allowed_packet);
|
type.set_length(max_allowed_packet);
|
||||||
ret = aggregate_charsets_for_string_result(type, types, 1, type_ctx.get_coll_type());
|
ret = aggregate_charsets_for_string_result(type, &text, 1, type_ctx.get_coll_type());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (OB_SUCC(ret)) {
|
if (OB_SUCC(ret)) {
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
#include "sql/engine/expr/ob_expr_util.h"
|
#include "sql/engine/expr/ob_expr_util.h"
|
||||||
#include "sql/engine/expr/ob_expr_regexp_count.h"
|
#include "sql/engine/expr/ob_expr_regexp_count.h"
|
||||||
#include "sql/engine/expr/ob_expr_lob_utils.h"
|
#include "sql/engine/expr/ob_expr_lob_utils.h"
|
||||||
|
#include "sql/resolver/expr/ob_raw_expr_util.h"
|
||||||
|
|
||||||
using namespace oceanbase::common;
|
using namespace oceanbase::common;
|
||||||
|
|
||||||
@ -45,12 +46,19 @@ int ObExprRegexpSubstr::calc_result_typeN(ObExprResType &type,
|
|||||||
UNUSED(type_ctx);
|
UNUSED(type_ctx);
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
ObRawExpr * raw_expr = type_ctx.get_raw_expr();
|
ObRawExpr * raw_expr = type_ctx.get_raw_expr();
|
||||||
|
const ObRawExpr * real_expr = NULL;
|
||||||
CK(NULL != type_ctx.get_raw_expr());
|
CK(NULL != type_ctx.get_raw_expr());
|
||||||
if (OB_FAIL(ret)) {
|
if (OB_FAIL(ret)) {
|
||||||
} else if (OB_UNLIKELY(param_num < 2 || param_num > 6)) {
|
} else if (OB_UNLIKELY(param_num < 2 || param_num > 6)) {
|
||||||
ret = OB_ERR_PARAM_SIZE;
|
ret = OB_ERR_PARAM_SIZE;
|
||||||
LOG_WARN("param number of regexp_substr at least 2 and at most 6", K(ret), K(param_num));
|
LOG_WARN("param number of regexp_substr at least 2 and at most 6", K(ret), K(param_num));
|
||||||
|
} else if (OB_FAIL(ObRawExprUtils::get_real_expr_without_cast(raw_expr->get_param_expr(0), real_expr))) {
|
||||||
|
LOG_WARN("fail to get real expr without cast", K(ret));
|
||||||
|
} else if (OB_ISNULL(real_expr)) {
|
||||||
|
ret = OB_ERR_UNEXPECTED;
|
||||||
|
LOG_WARN("real expr is invalid", K(ret), K(real_expr));
|
||||||
} else {
|
} else {
|
||||||
|
const ObExprResType &text = real_expr->get_result_type();
|
||||||
for (int i = 0; OB_SUCC(ret) && i < param_num; i++) {
|
for (int i = 0; OB_SUCC(ret) && i < param_num; i++) {
|
||||||
if (!types[i].is_null() && !is_type_valid(types[i].get_type())) {
|
if (!types[i].is_null() && !is_type_valid(types[i].get_type())) {
|
||||||
ret = OB_INVALID_ARGUMENT;
|
ret = OB_INVALID_ARGUMENT;
|
||||||
@ -61,8 +69,8 @@ int ObExprRegexpSubstr::calc_result_typeN(ObExprResType &type,
|
|||||||
//need duduce result type, then reset calc type.
|
//need duduce result type, then reset calc type.
|
||||||
if (lib::is_oracle_mode()) {
|
if (lib::is_oracle_mode()) {
|
||||||
// set max length.
|
// set max length.
|
||||||
type.set_length(static_cast<common::ObLength>(types[0].get_length()));
|
type.set_length(static_cast<common::ObLength>(text.get_length()));
|
||||||
auto str_params = make_const_carray(&types[0]);
|
auto str_params = make_const_carray(const_cast<ObExprResType*>(&text));
|
||||||
OZ(aggregate_string_type_and_charset_oracle(*type_ctx.get_session(),
|
OZ(aggregate_string_type_and_charset_oracle(*type_ctx.get_session(),
|
||||||
str_params,
|
str_params,
|
||||||
type,
|
type,
|
||||||
@ -74,8 +82,8 @@ int ObExprRegexpSubstr::calc_result_typeN(ObExprResType &type,
|
|||||||
? type_ctx.get_session()->get_actual_nls_length_semantics()
|
? type_ctx.get_session()->get_actual_nls_length_semantics()
|
||||||
: common::LS_BYTE);
|
: common::LS_BYTE);
|
||||||
type.set_varchar();
|
type.set_varchar();
|
||||||
type.set_length(types[0].get_length());
|
type.set_length(text.get_length());
|
||||||
type.set_length_semantics(types[0].is_varchar_or_char() ? types[0].get_length_semantics() : default_length_semantics);
|
type.set_length_semantics(text.is_varchar_or_char() ? text.get_length_semantics() : default_length_semantics);
|
||||||
ret = aggregate_charsets_for_string_result(type, types, 1, type_ctx.get_coll_type());
|
ret = aggregate_charsets_for_string_result(type, types, 1, type_ctx.get_coll_type());
|
||||||
}
|
}
|
||||||
if (OB_SUCC(ret)) {
|
if (OB_SUCC(ret)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user