patch 4.0

This commit is contained in:
wangzelin.wzl
2022-10-24 10:34:53 +08:00
parent 4ad6e00ec3
commit 93a1074b0c
10533 changed files with 2588271 additions and 2299373 deletions

View File

@ -17,20 +17,25 @@
#include "sql/engine/expr/ob_expr_result_type_util.h"
#include "sql/session/ob_sql_session_info.h"
namespace oceanbase {
namespace oceanbase
{
using namespace common;
namespace sql {
namespace sql
{
ObExprArgCase::ObExprArgCase(ObIAllocator& alloc)
: ObExprOperator(alloc, T_OP_ARG_CASE, N_ARG_CASE, MORE_THAN_ONE, NOT_ROW_DIMENSION), need_cast_(true)
ObExprArgCase::ObExprArgCase(ObIAllocator &alloc)
: ObExprOperator(alloc, T_OP_ARG_CASE,
N_ARG_CASE, MORE_THAN_ONE, NOT_ROW_DIMENSION,
INTERNAL_IN_MYSQL_MODE, INTERNAL_IN_ORACLE_MODE), need_cast_(true)
{
disable_operand_auto_cast();
}
ObExprArgCase::~ObExprArgCase()
{}
{
}
int ObExprArgCase::deserialize(const char* buf, const int64_t data_len, int64_t& pos)
int ObExprArgCase::deserialize(const char *buf, const int64_t data_len, int64_t &pos)
{
int ret = OB_SUCCESS;
need_cast_ = true;
@ -53,7 +58,7 @@ int ObExprArgCase::deserialize(const char* buf, const int64_t data_len, int64_t&
if (all_are_numeric && (!ob_is_accurate_numeric_type(type))) {
all_are_numeric = false;
}
} // end for
}//end for
if (OB_SUCC(ret)) {
need_cast_ = !(all_same_type || all_are_numeric);
}
@ -62,10 +67,10 @@ int ObExprArgCase::deserialize(const char* buf, const int64_t data_len, int64_t&
return ret;
}
int ObExprArgCase::assign(const ObExprOperator& other)
int ObExprArgCase::assign(const ObExprOperator &other)
{
int ret = OB_SUCCESS;
const ObExprArgCase* tmp_other = dynamic_cast<const ObExprArgCase*>(&other);
const ObExprArgCase *tmp_other = dynamic_cast<const ObExprArgCase *>(&other);
if (OB_UNLIKELY(NULL == tmp_other)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument. wrong type for other", K(ret), K(other));
@ -79,8 +84,15 @@ int ObExprArgCase::assign(const ObExprOperator& other)
return ret;
}
int ObExprArgCase::calc_result_typeN(
ObExprResType& type, ObExprResType* types_stack, int64_t param_num, ObExprTypeCtx& type_ctx) const
/*
* TODO: 这里没有计算compare type,可能导致结果和MySQL不兼容
* 目前做法是在calc_result中动态比较, 是否和MySQL行为一致?
*/
int ObExprArgCase::calc_result_typeN(ObExprResType &type,
ObExprResType *types_stack,
int64_t param_num,
ObExprTypeCtx &type_ctx) const
{
// mysql> drop table t1; create table t1(a date, b int);
// mysql> insert into t1 values (20160622, 20160622);
@ -94,6 +106,7 @@ int ObExprArgCase::calc_result_typeN(
// cmp type of '160622' VS a(date 2016-06-22) is date (or maybe datetime), equal.
// so we need a cmp type array, not a single cmp type.
// case c1
// when 10 then expr1
// when 11 then expr2
@ -104,10 +117,10 @@ int ObExprArgCase::calc_result_typeN(
if (OB_ISNULL(types_stack)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("null types", K(ret));
} else if (OB_UNLIKELY(param_num < 3 || param_num % 2 != 0)) { // an implicit 'else expr' element is added by caller
} else if (OB_UNLIKELY(param_num < 3 || param_num % 2 != 0)) { // an implicit 'else expr' element is added by caller
ret = OB_INVALID_ARGUMENT;
LOG_WARN("param_num is not correct", K(param_num));
} else { // param_num >= 4 and param_num is even
} else { // param_num >= 4 and param_num is even
/* take "case c1 when x1 then y1 when x2 then y2 else y3" as an example
After studying the behavior of mysql,
@ -117,24 +130,28 @@ int ObExprArgCase::calc_result_typeN(
int64_t cond_type_count = param_num / 2;
int64_t val_type_count = param_num / 2;
ObExprResType tmp_res_type;
const ObLengthSemantics default_length_semantics =
(OB_NOT_NULL(type_ctx.get_session()) ? type_ctx.get_session()->get_actual_nls_length_semantics() : LS_BYTE);
if (OB_FAIL(aggregate_result_type_for_case(tmp_res_type,
types_stack,
cond_type_count,
type_ctx.get_coll_type(),
lib::is_oracle_mode(),
default_length_semantics,
type_ctx.get_session(),
FALSE))) {
const ObLengthSemantics default_length_semantics = (OB_NOT_NULL(type_ctx.get_session()) ? type_ctx.get_session()->get_actual_nls_length_semantics() : LS_BYTE);
if (OB_FAIL(aggregate_result_type_for_case(
tmp_res_type,
types_stack,
cond_type_count,
type_ctx.get_coll_type(),
lib::is_oracle_mode(),
default_length_semantics,
type_ctx.get_session(),
FALSE, FALSE,
is_called_in_sql_))) {
LOG_WARN("failed to get result type for cmp", K(ret));
} else if (OB_FAIL(aggregate_result_type_for_case(type,
types_stack + cond_type_count,
val_type_count,
type_ctx.get_coll_type(),
lib::is_oracle_mode(),
default_length_semantics,
type_ctx.get_session()))) {
} else if (OB_FAIL(aggregate_result_type_for_case(
type,
types_stack + cond_type_count,
val_type_count,
type_ctx.get_coll_type(),
lib::is_oracle_mode(),
default_length_semantics,
type_ctx.get_session(),
true, false,
is_called_in_sql_))) {
LOG_WARN("failed to get result type", K(ret));
} else {
// cmp type will be computed dynamically
@ -144,8 +161,9 @@ int ObExprArgCase::calc_result_typeN(
for (int64_t i = 1; OB_SUCC(ret) && i < cond_type_count; ++i) {
ObObjType calc_type;
if (ob_is_enumset_tc(types_stack[i].get_type())) {
if (OB_FAIL(ObExprResultTypeUtil::get_relational_cmp_type(
calc_type, types_stack[0].get_type(), types_stack[i].get_type()))) {
if (OB_FAIL(ObExprResultTypeUtil::get_relational_cmp_type(calc_type,
types_stack[0].get_type(),
types_stack[i].get_type()))) {
LOG_WARN("failed to get_cmp_type", K(types_stack[0]), K(types_stack[i]), K(ret));
} else {
types_stack[i].set_calc_type(calc_type);
@ -157,22 +175,13 @@ int ObExprArgCase::calc_result_typeN(
return ret;
}
int ObExprArgCase::calc_resultN(ObObj& result, const ObObj* objs_stack, int64_t param_num, ObExprCtx& expr_ctx) const
{
int ret = OB_SUCCESS;
EXPR_DEFINE_CAST_CTX(expr_ctx, CM_NONE);
ObCompareCtx cmp_ctx(
ObMaxType, result_type_.get_calc_collation_type(), false, expr_ctx.tz_offset_, default_null_pos());
if (OB_UNLIKELY(need_cast_)) {
ret = calc_with_cast(result, objs_stack, param_num, cmp_ctx, cast_ctx, result_type_, ObExprArgCase::get_cmp_type);
} else {
ret = calc_without_cast(result, objs_stack, param_num, cast_ctx, cmp_ctx, result_type_);
}
return ret;
}
int ObExprArgCase::calc_with_cast(ObObj& result, const ObObj* objs_stack, int64_t param_num, ObCompareCtx& cmp_ctx,
ObCastCtx& cast_ctx, const ObExprResType& res_type, const ob_get_cmp_type_func get_cmp_type_func)
int ObExprArgCase::calc_with_cast(ObObj &result,
const ObObj *objs_stack,
int64_t param_num,
ObCompareCtx &cmp_ctx,
ObCastCtx &cast_ctx,
const ObExprResType &res_type,
const ob_get_cmp_type_func get_cmp_type_func)
{
int ret = OB_SUCCESS;
bool match_when = false;
@ -181,7 +190,7 @@ int ObExprArgCase::calc_with_cast(ObObj& result, const ObObj* objs_stack, int64_
if (OB_ISNULL(objs_stack) || OB_ISNULL(get_cmp_type_func)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("stack or get_cmp_type_func is null", K(objs_stack), K(get_cmp_type_func));
} else if (OB_UNLIKELY(param_num < 2)) {
} else if (OB_UNLIKELY(param_num < 2) ) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid param_num", K(param_num));
} else {
@ -198,15 +207,17 @@ int ObExprArgCase::calc_with_cast(ObObj& result, const ObObj* objs_stack, int64_
const bool has_else = (param_num % 2 == 0);
int64_t loop = (has_else) ? param_num - 2 : param_num;
for (int64_t i = 1; OB_SUCC(ret) && i < loop; i += 2) {
if (OB_FAIL(get_cmp_type_func(
cmp_ctx.cmp_type_, objs_stack[0].get_type(), objs_stack[i].get_type(), res_type.get_calc_type()))) {
if (OB_FAIL(get_cmp_type_func(cmp_ctx.cmp_type_,
objs_stack[0].get_type(),
objs_stack[i].get_type(),
res_type.get_calc_type()))) {
LOG_WARN("Get cmp type failed", K(ret));
} else {
cast_ctx.dest_collation_ = cmp_ctx.cmp_cs_type_;
ret = ObExprEqual::calc_cast(equal_result, objs_stack[0], objs_stack[i], cmp_ctx, cast_ctx);
if (OB_SUCC(ret)) {
if (ObNullType == equal_result.get_type()) {
} else if (OB_UNLIKELY(ObInt32Type != equal_result.get_type())) { // ObExprEqual::calc returns int32
} else if (OB_UNLIKELY(ObInt32Type != equal_result.get_type())) { // ObExprEqual::calc returns int32
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected calc result type. must be tiny", K(equal_result));
} else if (equal_result.is_true()) {
@ -221,7 +232,7 @@ int ObExprArgCase::calc_with_cast(ObObj& result, const ObObj* objs_stack, int64_
if (!match_when) {
if (param_num % 2 == 0) {
LOG_DEBUG("match else wrong", K(param_num));
tmp_result = objs_stack[param_num - 1]; // match else (default value)
tmp_result = objs_stack[param_num - 1]; // match else (default value)
} else {
tmp_result.set_null();
}
@ -233,8 +244,12 @@ int ObExprArgCase::calc_with_cast(ObObj& result, const ObObj* objs_stack, int64_
return ret;
}
int ObExprArgCase::calc_without_cast(ObObj& result, const ObObj* objs_stack, int64_t param_num, ObCastCtx& cast_ctx,
ObCompareCtx& cmp_ctx, const ObExprResType& res_type)
int ObExprArgCase::calc_without_cast(ObObj &result,
const ObObj *objs_stack,
int64_t param_num,
ObCastCtx &cast_ctx,
ObCompareCtx &cmp_ctx,
const ObExprResType &res_type)
{
int ret = OB_SUCCESS;
bool match_when = false;
@ -244,7 +259,7 @@ int ObExprArgCase::calc_without_cast(ObObj& result, const ObObj* objs_stack, int
if (OB_ISNULL(objs_stack)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("stack is null", K(objs_stack), K(ret));
} else if (OB_UNLIKELY(param_num < 2)) {
} else if (OB_UNLIKELY(param_num < 2) ) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid param_num", K(param_num));
} else {
@ -270,7 +285,7 @@ int ObExprArgCase::calc_without_cast(ObObj& result, const ObObj* objs_stack, int
LOG_WARN("unexpected error. cast should not be necessary", K(objs_stack[0]), K(objs_stack[i]), K(ret));
} else {
if (ObNullType == equal_result.get_type()) {
} else if (OB_UNLIKELY(ObInt32Type != equal_result.get_type())) { // ObExprEqual::calc returns int32 result
} else if (OB_UNLIKELY(ObInt32Type != equal_result.get_type())) { // ObExprEqual::calc returns int32 result
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected calc result type. must be tiny", K(equal_result));
} else if (equal_result.is_true()) {
@ -279,29 +294,28 @@ int ObExprArgCase::calc_without_cast(ObObj& result, const ObObj* objs_stack, int
break;
}
}
} // end for
}//end for
if (OB_SUCC(ret)) {
if (!match_when) {
if (param_num % 2 == 0) {
LOG_DEBUG("match else wrong", K(param_num));
tmp_result = objs_stack[param_num - 1]; // match else (default value)
tmp_result = objs_stack[param_num - 1]; // match else (default value)
} else {
tmp_result.set_null();
}
}
cast_ctx.dest_collation_ = res_type.get_collation_type();
ret = ObObjCaster::to_type(res_type.get_type(), res_type.get_collation_type(), cast_ctx, tmp_result, result);
} // end ob_succ(ret)
}//end ob_succ(ret)
}
return ret;
}
int ObExprArgCase::cg_expr(ObExprCGCtx&, const ObRawExpr&, ObExpr&) const
int ObExprArgCase::cg_expr(ObExprCGCtx &, const ObRawExpr &, ObExpr &) const
{
int ret = OB_ERR_UNEXPECTED;
LOG_WARN("this expr should be rewrote in new engine", K(ret));
return ret;
}
} // namespace sql
} // namespace oceanbase
}
}