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

@ -24,10 +24,12 @@
#include "lib/json_type/ob_json_base.h"
#include "lib/json_type/ob_json_bin.h"
namespace oceanbase {
namespace oceanbase
{
using namespace common;
using namespace share;
namespace sql {
namespace sql
{
OB_DEF_SERIALIZE_SIZE(ObInfixExprItem)
{
@ -70,7 +72,7 @@ OB_DEF_DESERIALIZE(ObInfixExprItem)
}
// same with ob_write_expr_item in ob_postfix_expression.cpp
int ObInfixExprItem::deep_copy(common::ObIAllocator& alloc, const bool only_obj /* = false */)
int ObInfixExprItem::deep_copy(common::ObIAllocator &alloc, const bool only_obj /* = false */)
{
int ret = OB_SUCCESS;
if (T_REF_COLUMN == item_type_) {
@ -80,12 +82,12 @@ int ObInfixExprItem::deep_copy(common::ObIAllocator& alloc, const bool only_obj
if (OB_FAIL(ob_write_obj(alloc, get_obj(), obj))) {
LOG_WARN("copy object failed", K(ret));
} else {
*reinterpret_cast<ObObj*>(&v2_.v1_) = obj;
*reinterpret_cast<ObObj *>(&v2_.v1_) = obj;
}
} else if (IS_EXPR_OP(item_type_)) {
if (!only_obj) {
ObExprOperatorFactory factory(alloc);
ObExprOperator* op = NULL;
ObExprOperator *op = NULL;
if (OB_FAIL(factory.alloc(item_type_, op))) {
LOG_WARN("alloc expr operator failed", K(ret));
} else if (OB_ISNULL(op)) {
@ -104,13 +106,15 @@ int ObInfixExprItem::deep_copy(common::ObIAllocator& alloc, const bool only_obj
return ret;
}
ObInfixExpression::ObInfixExpression(ObIAllocator& alloc, const int64_t expr_cnt) : alloc_(alloc), exprs_()
ObInfixExpression::ObInfixExpression(ObIAllocator &alloc, const int64_t expr_cnt)
: alloc_(alloc), exprs_()
{
UNUSED(expr_cnt);
}
ObInfixExpression::~ObInfixExpression()
{}
{
}
void ObInfixExpression::reset()
{
@ -160,13 +164,11 @@ int ObInfixExpression::set_item_count(const int64_t count)
if (count < 0 || count >= std::numeric_limits<uint16_t>::max()) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid item count", K(ret), K(count));
} else if (OB_FAIL(exprs_.init(count, alloc_))) {
LOG_WARN("exprs init failed", K(ret));
}
return ret;
return exprs_.init(count, alloc_);
}
int ObInfixExpression::assign(const ObInfixExpression& other)
int ObInfixExpression::assign(const ObInfixExpression &other)
{
int ret = OB_SUCCESS;
if (this != &other) {
@ -174,8 +176,7 @@ int ObInfixExpression::assign(const ObInfixExpression& other)
if (OB_FAIL(exprs_.reserve(other.exprs_.count(), alloc_))) {
LOG_WARN("array reserve failed", K(ret));
} else {
FOREACH_CNT_X(item, other.exprs_, OB_SUCC(ret))
{
FOREACH_CNT_X(item, other.exprs_, OB_SUCC(ret)) {
if (OB_FAIL(exprs_.push_back(*item))) {
LOG_WARN("array push back failed", K(ret));
} else {
@ -190,7 +191,7 @@ int ObInfixExpression::assign(const ObInfixExpression& other)
return ret;
}
int ObInfixExpression::add_expr_item(const ObInfixExprItem& item)
int ObInfixExpression::add_expr_item(const ObInfixExprItem &item)
{
int ret = OB_SUCCESS;
const bool copy_obj_only = true;
@ -201,7 +202,7 @@ int ObInfixExpression::add_expr_item(const ObInfixExprItem& item)
} else if (OB_FAIL(exprs_.push_back(item))) {
LOG_WARN("array push back failed", K(ret));
} else {
ObInfixExprItem& new_item = exprs_.at(exprs_.count() - 1);
ObInfixExprItem &new_item = exprs_.at(exprs_.count() - 1);
if (OB_FAIL(new_item.deep_copy(alloc_, copy_obj_only))) {
LOG_WARN("expr deep copy failed", K(ret));
} else if (IS_EXPR_OP(new_item.get_item_type())) {
@ -219,63 +220,68 @@ int ObInfixExpression::add_expr_item(const ObInfixExprItem& item)
}
// FREE_EVAL_STACK must called in same code block
#define ALLOC_EVAL_STACK \
const int64_t _stack_size = exprs_.count(); \
const int64_t _stack_alloc_size = _stack_size < STACK_ALLOC_STACK_SIZE ? _stack_size : 0; \
char _buf[_stack_alloc_size * sizeof(ObObj)]; \
bool _use_global_stack = false; \
ObObj* stack = reinterpret_cast<ObObj*>(_buf); \
if (OB_UNLIKELY(0 == _stack_alloc_size)) { \
int64_t& _cur_top = global_stack_top(); \
auto* _calc_stack = global_stack(); \
if (OB_ISNULL(_calc_stack)) { \
ret = OB_ALLOCATE_MEMORY_FAILED; \
LOG_WARN("get thread local stack failed", K(ret)); \
} else if (OB_UNLIKELY(_stack_size + _cur_top > ObPostfixExpressionCalcStack::STACK_SIZE)) { \
if (NULL == (stack = static_cast<ObObj*>(expr_ctx.calc_buf_->alloc(sizeof(ObObj) * _stack_size)))) { \
ret = OB_ALLOCATE_MEMORY_FAILED; \
LOG_WARN("get thread local stack failed", K(ret)); \
} \
} else { \
_use_global_stack = true; \
stack = _calc_stack->stack_ + _cur_top; \
_cur_top += _stack_size; \
} \
} \
/* set stack to expr_ctx */
#define ALLOC_EVAL_STACK \
const int64_t _stack_size = exprs_.count(); \
const int64_t _stack_alloc_size = _stack_size < STACK_ALLOC_STACK_SIZE ? _stack_size : 0; \
char _buf[_stack_alloc_size * sizeof(ObObj)]; \
bool _use_global_stack = false; \
ObObj *stack = reinterpret_cast<ObObj *>(_buf); \
if (OB_UNLIKELY(0 == _stack_alloc_size)) { \
int64_t &_cur_top = global_stack_top(); \
auto *_calc_stack = global_stack(); \
if (OB_ISNULL(_calc_stack)) { \
ret = OB_ALLOCATE_MEMORY_FAILED; \
LOG_WARN("get thread local stack failed", K(ret)); \
} else if (OB_UNLIKELY(_stack_size + _cur_top > ObPostfixExpressionCalcStack::STACK_SIZE)) { \
if (NULL == (stack = static_cast<ObObj *>(expr_ctx.calc_buf_->alloc( \
sizeof(ObObj) * _stack_size)))) { \
ret = OB_ALLOCATE_MEMORY_FAILED; \
LOG_WARN("get thread local stack failed", K(ret)); \
} \
} else { \
_use_global_stack = true; \
stack = _calc_stack->stack_ + _cur_top; \
_cur_top += _stack_size; \
} \
} \
/* set stack to expr_ctx */ \
#define FREE_EVAL_STACK \
if (OB_UNLIKELY(0 == _stack_alloc_size)) { \
if (_use_global_stack) { \
int64_t& _cur_top = global_stack_top(); \
_cur_top -= _stack_size; \
} \
#define FREE_EVAL_STACK \
if (OB_UNLIKELY(0 == _stack_alloc_size)) { \
if (_use_global_stack) { \
int64_t &_cur_top = global_stack_top();\
_cur_top -= _stack_size; \
} \
}
#define SAVE_EVAL_CTX(ctx, stack, r1, r2) \
do { \
ctx.infix_expr_ = this; \
ctx.stack_ = stack; \
ctx.row1_ = r1; \
ctx.row2_ = r2; \
} while (false)
do { \
ctx.infix_expr_ = this; \
ctx.stack_ = stack; \
ctx.row1_ = r1; \
ctx.row2_ = r2; \
} while (false)
int ObInfixExpression::calc(common::ObExprCtx& expr_ctx, const common::ObNewRow& row, common::ObObj& val) const
int ObInfixExpression::calc(common::ObExprCtx &expr_ctx,
const common::ObNewRow &row, common::ObObj &val) const
{
int ret = OB_SUCCESS;
#ifdef NDEBUG
// prefetch for read
__builtin_prefetch(&exprs_.at(0), 0);
#endif
if (OB_LIKELY(1 == exprs_.count()) && OB_LIKELY(exprs_.at(0).can_get_value_directly())) {
const ObObj* value = NULL;
if (OB_FAIL(exprs_.at(0).get_item_value_directly(*expr_ctx.phy_plan_ctx_, row, value)) || OB_ISNULL(value)) {
if (OB_LIKELY(1 == exprs_.count())
&& OB_LIKELY(exprs_.at(0).can_get_value_directly())) {
const ObObj *value = NULL;
if (OB_FAIL(exprs_.at(0).get_item_value_directly(*expr_ctx.phy_plan_ctx_, row, value))
|| OB_ISNULL(value)) {
ret = COVER_SUCC(OB_ERR_UNEXPECTED);
LOG_WARN("get item value directly failed", K(ret), K(row), K_(exprs));
} else if (value->is_ext() && ObSqlExpressionUtil::expand_array_params(expr_ctx, *value, value)) {
LOG_WARN("expand array params failed", K(ret));
} else {
val = *value;
val= *value;
}
} else if (OB_UNLIKELY(exprs_.at(0).get_item_type() == T_OP_SHADOW_UK_PROJECT)) {
if (OB_FAIL(uk_fast_project(expr_ctx, row, val))) {
@ -302,8 +308,8 @@ int ObInfixExpression::calc(common::ObExprCtx& expr_ctx, const common::ObNewRow&
return ret;
}
int ObInfixExpression::calc(
common::ObExprCtx& expr_ctx, const common::ObNewRow& row1, const common::ObNewRow& row2, common::ObObj& val) const
int ObInfixExpression::calc(common::ObExprCtx &expr_ctx, const common::ObNewRow &row1,
const common::ObNewRow &row2, common::ObObj &val) const
{
int ret = OB_SUCCESS;
@ -326,8 +332,8 @@ int ObInfixExpression::calc(
return ret;
}
int ObInfixExpression::calc_row(common::ObExprCtx& expr_ctx,
const common::ObNewRow& row, ObItemType aggr_fun, common::ObNewRow &res_row) const
int ObInfixExpression::calc_row(common::ObExprCtx &expr_ctx,
const common::ObNewRow &row, ObItemType aggr_fun, common::ObNewRow &res_row) const
{
int ret = OB_SUCCESS;
@ -340,7 +346,7 @@ int ObInfixExpression::calc_row(common::ObExprCtx& expr_ctx,
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument", K(ret), K(exprs_.count()));
} else {
const ObInfixExprItem& item = exprs_.at(0);
const ObInfixExprItem &item = exprs_.at(0);
if (OB_UNLIKELY(T_OP_AGG_PARAM_LIST == item.get_item_type())) {
for (int64_t i = 0; i < item.get_param_num() && OB_SUCC(ret); i++) {
if (OB_FAIL(eval(expr_ctx, row, stack, item.get_param_idx() + i))) {
@ -365,9 +371,10 @@ int ObInfixExpression::calc_row(common::ObExprCtx& expr_ctx,
if (OB_SUCC(ret)) {
if (OB_UNLIKELY(item.get_param_num() > res_row.count_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("to small result row count", K(ret), K(item), K(res_row.count_));
LOG_WARN("to small result row count", K(ret), K(item), K(res_row.count_));
} else {
MEMCPY(res_row.cells_, stack + item.get_param_idx(), sizeof(ObObj) * item.get_param_num());
MEMCPY(res_row.cells_, stack + item.get_param_idx(),
sizeof(ObObj) * item.get_param_num());
}
}
} else {
@ -403,12 +410,12 @@ int ObInfixExpression::calc_row(common::ObExprCtx& expr_ctx,
#undef SAVE_EVAL_CTX
#undef FREE_EVAL_STACK
int ObInfixExpression::eval(
common::ObExprCtx& ctx, const common::ObNewRow& row, common::ObObj* stack, const int64_t pos) const
int ObInfixExpression::eval(common::ObExprCtx &ctx, const common::ObNewRow &row,
common::ObObj *stack, const int64_t pos) const
{
int ret = OB_SUCCESS;
const ObInfixExprItem& item = exprs_.at(pos);
if (item.get_param_num() > 0) {
const ObInfixExprItem &item = exprs_.at(pos);
if (item.get_param_num() > 0 ) {
// prefetch for read
__builtin_prefetch(&exprs_.at(item.get_param_idx()), 0);
if (!item.is_param_lazy_eval()) {
@ -428,19 +435,21 @@ int ObInfixExpression::eval(
const int64_t idx = item.get_column();
if (OB_LIKELY(idx >= 0 && OB_LIKELY(idx < row.count_) && OB_LIKELY(NULL != row.cells_))) {
stack[pos] = row.cells_[idx];
if (OB_UNLIKELY(ObBitType == stack[pos].get_type() && -1 != item.get_accuracy().get_precision())) {
// use object scale to store bit length
if (OB_UNLIKELY(ObBitType == stack[pos].get_type() &&
-1 != item.get_accuracy().get_precision())) {
//use object scale to store bit length
stack[pos].set_scale(item.get_accuracy().get_precision());
} else if (OB_UNLIKELY(ob_is_text_tc(stack[pos].get_type()))) {
// do nothing ...
//do nothing ...
} else if (-1 != item.get_accuracy().get_scale()) {
stack[pos].set_scale(item.get_accuracy().get_scale());
}
} else if (NULL != ctx.row2_ && NULL != ctx.row2_->cells_ && idx >= row.count_ &&
idx - row.count_ < ctx.row2_->count_) {
} else if (NULL != ctx.row2_ && NULL != ctx.row2_->cells_
&& idx >= row.count_ && idx - row.count_ < ctx.row2_->count_) {
stack[pos] = ctx.row2_->cells_[idx - row.count_];
if (OB_UNLIKELY(ObBitType == stack[pos].get_type() && -1 != item.get_accuracy().get_precision())) {
// use object scale to store bit length
if (OB_UNLIKELY(ObBitType == stack[pos].get_type() &&
-1 != item.get_accuracy().get_precision())) {
//use object scale to store bit length
stack[pos].set_scale(item.get_accuracy().get_precision());
} else if (-1 != item.get_accuracy().get_scale()) {
stack[pos].set_scale(item.get_accuracy().get_scale());
@ -450,7 +459,7 @@ int ObInfixExpression::eval(
LOG_WARN("cell index out of range", K(idx), K(row), K(ctx.row2_));
}
} else if (T_QUESTIONMARK == item.get_item_type()) {
const ObObj* obj = NULL;
const ObObj *obj = NULL;
if (OB_FAIL(item.get_indirect_const(*ctx.phy_plan_ctx_, obj)) || OB_ISNULL(obj)) {
ret = COVER_SUCC(OB_ERR_UNEXPECTED);
LOG_WARN("get obj failed", K(ret));
@ -462,38 +471,33 @@ int ObInfixExpression::eval(
} else if (IS_DATATYPE_OP(item.get_item_type())) {
stack[pos] = item.get_obj();
} else if (IS_EXPR_OP(item.get_item_type())) {
const ObExprOperator* op = item.get_expr_operator();
const ObExprOperator *op = item.get_expr_operator();
if (OB_ISNULL(op)) {
ret = OB_BAD_NULL_ERROR;
LOG_WARN("expr operator is NULL", K(ret));
} else if (OB_FAIL(op->eval(ctx, stack[pos], stack + item.get_param_idx(), item.get_param_num()))) {
LOG_WARN("expr evaluate failed",
K(ret),
"type",
item.get_item_type(),
"type_name",
get_type_name(item.get_item_type()));
} else {
} else if (OB_FAIL(op->eval(ctx, stack[pos],
stack + item.get_param_idx(), item.get_param_num()))) {
LOG_WARN("expr evaluate failed", K(ret),
"type", item.get_item_type(),
"type_name", get_type_name(item.get_item_type()));
} else {
// For expression op, we need set scale info after it has been evaluated.
if (OB_UNLIKELY(ObBitType == stack[pos].get_type() && -1 != item.get_accuracy().get_precision())) {
if (OB_UNLIKELY(ObBitType == stack[pos].get_type() &&
-1 != item.get_accuracy().get_precision())) {
// use object scale to store bit length
stack[pos].set_scale(item.get_accuracy().get_precision());
}
}
} else {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid expression operator",
K(ret),
"type",
item.get_item_type(),
"type_name",
get_type_name(item.get_item_type()));
LOG_WARN("invalid expression operator", K(ret),
"type", item.get_item_type(),
"type_name", get_type_name(item.get_item_type()));
}
}
// when case of parameter eval failure, the parameter value is set to NULL,
// because the parameter ObObj has not been initialized before.
// If it is not forcibly set to NULL, if the parameter is printed in the log stack later,
// it may cause core
// 此处在参数eval失败的情况下, 将该参数值设置为NULL, 因为该参数值
// ObObj之前没有初始化过, 如果不强制设置为NULL, 后面日志栈中如果出现
// 打印该参数的情况可能导致core
if (OB_FAIL(ret)) {
stack[pos].set_null();
}
@ -501,7 +505,7 @@ int ObInfixExpression::eval(
}
// copy && paste from ob_postfix_expression.cpp
int ObInfixExpression::generate_idx_for_regexp_ops(int16_t& cur_regexp_op_count)
int ObInfixExpression::generate_idx_for_regexp_ops(int16_t &cur_regexp_op_count)
{
/*please note that, cur_regexp_op_count is a reference of a variable in ObCodeGeneratorImpl
* it is used as a total counter here
@ -511,7 +515,7 @@ int ObInfixExpression::generate_idx_for_regexp_ops(int16_t& cur_regexp_op_count)
int ret = OB_SUCCESS;
for (int64_t i = 0; OB_SUCC(ret) && i < exprs_.count(); ++i) {
if (T_OP_REGEXP == exprs_.at(i).get_item_type()) {
ObExprRegexp* regexp_op = static_cast<ObExprRegexp*>(exprs_.at(i).get_expr_operator());
ObExprRegexp *regexp_op = static_cast<ObExprRegexp *>(exprs_.at(i).get_expr_operator());
if (OB_ISNULL(regexp_op)) {
ret = OB_BAD_NULL_ERROR;
LOG_WARN("regexp op is null", K(ret));
@ -524,13 +528,15 @@ int ObInfixExpression::generate_idx_for_regexp_ops(int16_t& cur_regexp_op_count)
}
// copy && paste from ob_postfix_expression.cpp
bool ObInfixExpression::is_equijoin_cond(int64_t& c1, int64_t& c2, common::ObObjType& cmp_type,
common::ObCollationType& cmp_cs_type, bool& is_null_safe) const
bool ObInfixExpression::is_equijoin_cond(int64_t &c1, int64_t &c2,
common::ObObjType &cmp_type, common::ObCollationType &cmp_cs_type,
bool &is_null_safe) const
{
bool ret = false;
if (exprs_.count() == 3) {
if ((exprs_[0].get_item_type() == T_OP_EQ || exprs_[0].get_item_type() == T_OP_NSEQ) &&
exprs_[1].get_item_type() == T_REF_COLUMN && exprs_[2].get_item_type() == T_REF_COLUMN) {
if ((exprs_[0].get_item_type() == T_OP_EQ || exprs_[0].get_item_type() == T_OP_NSEQ)
&& exprs_[1].get_item_type() == T_REF_COLUMN
&& exprs_[2].get_item_type() == T_REF_COLUMN) {
c1 = exprs_[1].get_column();
c2 = exprs_[2].get_column();
cmp_type = exprs_[0].get_expr_operator()->get_result_type().get_calc_type();
@ -545,8 +551,8 @@ bool ObInfixExpression::is_equijoin_cond(int64_t& c1, int64_t& c2, common::ObObj
}
// copy && paste from ob_postfix_expression.cpp
int ObInfixExpression::uk_fast_project(
common::ObExprCtx& expr_ctx, const common::ObNewRow& row, common::ObObj& result_val) const
int ObInfixExpression::uk_fast_project(common::ObExprCtx &expr_ctx, const common::ObNewRow &row,
common::ObObj &result_val) const
{
int ret = OB_SUCCESS;
int64_t expr_cnt = exprs_.count();
@ -568,18 +574,15 @@ int ObInfixExpression::uk_fast_project(
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(ObUniqueIndexRowTransformer::check_need_shadow_columns(row,
static_cast<ObCompatibilityMode>(THIS_WORKER.get_compatibility_mode()),
unique_key_cnt,
&projector,
expr_ctx.row_ctx_.is_uk_cnt_null_))) {
if (OB_FAIL(ObUniqueIndexRowTransformer::check_need_shadow_columns(row, static_cast<ObCompatibilityMode>(THIS_WORKER.get_compatibility_mode()), unique_key_cnt,
&projector, expr_ctx.row_ctx_.is_uk_cnt_null_))) {
LOG_WARN("fail to check need shadow columns", K(ret));
}
}
expr_ctx.row_ctx_.is_uk_checked_ = true;
}
if (OB_SUCC(ret)) {
const ObPostExprItem& item = exprs_.at(unique_key_cnt + 1);
const ObPostExprItem &item = exprs_.at(unique_key_cnt + 1);
if (!expr_ctx.row_ctx_.is_uk_cnt_null_) {
result_val.set_null();
} else if (OB_UNLIKELY(item.get_item_type() != T_REF_COLUMN)) {
@ -598,5 +601,5 @@ int ObInfixExpression::uk_fast_project(
return ret;
}
} // end namespace sql
} // end namespace oceanbase
} // end namespace sql
} // end namespace oceanbase