patch 4.0
This commit is contained in:
@ -19,13 +19,16 @@
|
||||
#include "sql/engine/expr/ob_expr_like.h"
|
||||
#include "lib/utility/ob_hang_fatal_error.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace oceanbase
|
||||
{
|
||||
using namespace common;
|
||||
using namespace share;
|
||||
namespace sql {
|
||||
namespace sql
|
||||
{
|
||||
|
||||
template <typename AllocatorT>
|
||||
int ob_write_expr_item(AllocatorT& alloc, const ObPostExprItem& src, ObPostExprItem& dst, ObWriteExprItemFlag flag)
|
||||
int ob_write_expr_item(AllocatorT &alloc, const ObPostExprItem &src,
|
||||
ObPostExprItem &dst, ObWriteExprItemFlag flag)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObItemType item_type = src.get_item_type();
|
||||
@ -42,7 +45,7 @@ int ob_write_expr_item(AllocatorT& alloc, const ObPostExprItem& src, ObPostExprI
|
||||
}
|
||||
} else if (IS_EXPR_OP(item_type)) {
|
||||
if (NEW_OP_WHEN_COPY == flag) {
|
||||
ObExprOperator* op = NULL;
|
||||
ObExprOperator *op = NULL;
|
||||
if (OB_FAIL(factory.alloc(item_type, op))) {
|
||||
LOG_WARN("fail to alloc expr_op", K(ret));
|
||||
} else if (OB_ISNULL(op)) {
|
||||
@ -60,7 +63,7 @@ int ob_write_expr_item(AllocatorT& alloc, const ObPostExprItem& src, ObPostExprI
|
||||
if (OB_ISNULL(src.get_expr_operator())) {
|
||||
ret = OB_BAD_NULL_ERROR;
|
||||
LOG_WARN("src expr op is null", K(ret));
|
||||
} else if (OB_FAIL(dst.assign(const_cast<ObPostExprItem&>(src).get_expr_operator()))) {
|
||||
} else if (OB_FAIL(dst.assign(const_cast<ObPostExprItem &>(src).get_expr_operator()))) {
|
||||
LOG_WARN("failed to assign dst expr item", K(ret));
|
||||
}
|
||||
}
|
||||
@ -71,7 +74,8 @@ int ob_write_expr_item(AllocatorT& alloc, const ObPostExprItem& src, ObPostExprI
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPostExprItem::assign(const common::ObObj& obj)
|
||||
|
||||
int ObPostExprItem::assign(const common::ObObj &obj)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObItemType item_type = static_cast<ObItemType>((obj.get_type()));
|
||||
@ -79,7 +83,7 @@ int ObPostExprItem::assign(const common::ObObj& obj)
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid obj type", K(ret), K(obj));
|
||||
} else {
|
||||
new (&v2_.v1_) ObObj(obj);
|
||||
new(&v2_.v1_) ObObj(obj);
|
||||
item_type_ = item_type;
|
||||
}
|
||||
return ret;
|
||||
@ -98,7 +102,7 @@ int ObPostExprItem::set_column(int64_t index)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPostExprItem::assign(ObExprOperator* op)
|
||||
int ObPostExprItem::assign(ObExprOperator *op)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(op)) {
|
||||
@ -124,7 +128,7 @@ int ObPostExprItem::assign(ObItemType item_type)
|
||||
}
|
||||
|
||||
/* for unittest only */
|
||||
int ObPostExprItem::set_op(ObIAllocator& alloc, const char* op_name, ObExprOperator*& op)
|
||||
int ObPostExprItem::set_op(ObIAllocator &alloc, const char *op_name, ObExprOperator *&op)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObExprOperatorType type = ObExprOperatorFactory::get_type_by_name(ObString::make_string(op_name));
|
||||
@ -145,14 +149,14 @@ int ObPostExprItem::set_op(ObIAllocator& alloc, const char* op_name, ObExprOpera
|
||||
|
||||
/* for unittest only */
|
||||
/* so need NOT normalize */
|
||||
void ObPostExprItem::set_op(ObIAllocator& alloc, const char* op_name, int32_t real_param_num)
|
||||
void ObPostExprItem::set_op(ObIAllocator &alloc, const char *op_name, int32_t real_param_num)
|
||||
{
|
||||
ObExprOperatorType type = ObExprOperatorFactory::get_type_by_name(ObString::make_string(op_name));
|
||||
if (T_INVALID == type) {
|
||||
LOG_ERROR("invaid op type", K(type));
|
||||
right_to_die_or_duty_to_live();
|
||||
} else {
|
||||
ObExprOperator* op = NULL;
|
||||
ObExprOperator *op = NULL;
|
||||
ObExprOperatorFactory factory(alloc);
|
||||
factory.alloc(type, op);
|
||||
if (OB_ISNULL(op)) {
|
||||
@ -163,19 +167,22 @@ void ObPostExprItem::set_op(ObIAllocator& alloc, const char* op_name, int32_t re
|
||||
}
|
||||
}
|
||||
|
||||
int64_t ObPostExprItem::to_string(char* buf, const int64_t buf_len) const
|
||||
int64_t ObPostExprItem::to_string(char *buf, const int64_t buf_len) const
|
||||
{
|
||||
int64_t pos = 0;
|
||||
if (IS_DATATYPE_OP(item_type_)) {
|
||||
J_OW(J_KV(N_CONST, get_obj(), N_ACCURACY, accuracy_));
|
||||
J_OW(J_KV(N_CONST, get_obj(),
|
||||
N_ACCURACY, accuracy_));
|
||||
} else {
|
||||
switch (item_type_) {
|
||||
case T_REF_COLUMN: {
|
||||
J_OW(J_KV(N_COLUMN_INDEX, get_column(), N_ACCURACY, accuracy_));
|
||||
J_OW(J_KV(N_COLUMN_INDEX, get_column(),
|
||||
N_ACCURACY, accuracy_));
|
||||
break;
|
||||
}
|
||||
case T_QUESTIONMARK: {
|
||||
J_OW(J_KV(N_PARAM, get_obj().get_int(), N_ACCURACY, accuracy_));
|
||||
J_OW(J_KV(N_PARAM, get_obj().get_int(),
|
||||
N_ACCURACY, accuracy_));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@ -186,7 +193,7 @@ int64_t ObPostExprItem::to_string(char* buf, const int64_t buf_len) const
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // end switch
|
||||
} // end switch
|
||||
}
|
||||
|
||||
return pos;
|
||||
@ -214,7 +221,10 @@ DEFINE_SERIALIZE(ObPostExprItem)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPostExprItem::deserialize(ObIAllocator& alloc, const char* buf, const int64_t data_len, int64_t& pos)
|
||||
int ObPostExprItem::deserialize(ObIAllocator &alloc,
|
||||
const char *buf,
|
||||
const int64_t data_len,
|
||||
int64_t &pos)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
OB_UNIS_DECODE(item_type_);
|
||||
@ -229,7 +239,7 @@ int ObPostExprItem::deserialize(ObIAllocator& alloc, const char* buf, const int6
|
||||
if (OB_FAIL(deep_copy_obj(alloc, tmp, local_mem_obj))) {
|
||||
LOG_WARN("failed to deep copy obj", K(ret));
|
||||
} else {
|
||||
new (&v2_.v1_) ObObj(local_mem_obj);
|
||||
new(&v2_.v1_) ObObj(local_mem_obj);
|
||||
OB_UNIS_DECODE(accuracy_);
|
||||
}
|
||||
} else if (IS_EXPR_OP(item_type_)) {
|
||||
@ -271,8 +281,10 @@ DEFINE_GET_SERIALIZE_SIZE(ObPostExprItem)
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
ObPostfixExpression::ObPostfixExpression(ObIAllocator& alloc, int64_t item_count)
|
||||
: post_exprs_(), str_buf_(alloc), output_column_count_(1)
|
||||
ObPostfixExpression::ObPostfixExpression(ObIAllocator &alloc, int64_t item_count)
|
||||
: post_exprs_(),
|
||||
str_buf_(alloc),
|
||||
output_column_count_(1) //默认为1
|
||||
{
|
||||
UNUSED(item_count);
|
||||
}
|
||||
@ -293,7 +305,7 @@ void ObPostfixExpression::data_clear()
|
||||
output_column_count_ = 1;
|
||||
}
|
||||
|
||||
int ObPostfixExpression::assign(const ObPostfixExpression& other)
|
||||
int ObPostfixExpression::assign(const ObPostfixExpression &other)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (&other != this) {
|
||||
@ -303,20 +315,20 @@ int ObPostfixExpression::assign(const ObPostfixExpression& other)
|
||||
} else {
|
||||
ObPostExprItem item_clone;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < other.post_exprs_.count(); ++i) {
|
||||
const ObPostExprItem& item = other.post_exprs_[i];
|
||||
const ObPostExprItem &item = other.post_exprs_[i];
|
||||
if (OB_FAIL(ob_write_expr_item(str_buf_, item, item_clone, NEW_OP_WHEN_COPY))) {
|
||||
LOG_WARN("failed to deep copy expr item", K(ret));
|
||||
} else if (OB_FAIL(post_exprs_.push_back(item_clone))) {
|
||||
LOG_WARN("failed to push into array", K(ret));
|
||||
}
|
||||
} // end for
|
||||
} // end for
|
||||
output_column_count_ = other.output_column_count_;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPostfixExpression::add_expr_item(const ObPostExprItem& item)
|
||||
int ObPostfixExpression::add_expr_item(const ObPostExprItem &item)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObPostExprItem item_clone;
|
||||
@ -328,7 +340,7 @@ int ObPostfixExpression::add_expr_item(const ObPostExprItem& item)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPostfixExpression::generate_idx_for_regexp_ops(int16_t& cur_regexp_op_count)
|
||||
int ObPostfixExpression::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
|
||||
@ -338,7 +350,7 @@ int ObPostfixExpression::generate_idx_for_regexp_ops(int16_t& cur_regexp_op_coun
|
||||
int ret = OB_SUCCESS;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < post_exprs_.count(); ++i) {
|
||||
if (T_OP_REGEXP == post_exprs_.at(i).get_item_type()) {
|
||||
ObExprRegexp* regexp_op = static_cast<ObExprRegexp*>(post_exprs_.at(i).get_expr_operator());
|
||||
ObExprRegexp *regexp_op = static_cast<ObExprRegexp *>(post_exprs_.at(i).get_expr_operator());
|
||||
if (OB_ISNULL(regexp_op)) {
|
||||
ret = OB_BAD_NULL_ERROR;
|
||||
LOG_WARN("regexp op is null", K(ret));
|
||||
@ -350,19 +362,20 @@ int ObPostfixExpression::generate_idx_for_regexp_ops(int16_t& cur_regexp_op_coun
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPostfixExpression::calc(common::ObExprCtx& expr_ctx, const common::ObNewRow& row, ObObj& result_val) const
|
||||
int ObPostfixExpression::calc(common::ObExprCtx &expr_ctx, const common::ObNewRow &row,
|
||||
ObObj &result_val) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t last_idx = post_exprs_.count() - 1;
|
||||
if (OB_LIKELY(1 == post_exprs_.count()) && OB_LIKELY(post_exprs_.at(0).can_get_value_directly())) {
|
||||
const ObObj* value = NULL;
|
||||
const ObObj *value = NULL;
|
||||
if (OB_FAIL(post_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_(post_exprs));
|
||||
} else if (!expr_ctx.is_pre_calculation_) {
|
||||
// in pre calculation, if only one question mark expr, return the question mark expression
|
||||
// result directly, even if it is a param array, this is to avoid constructing a param array
|
||||
// in the pre calculation
|
||||
//in pre calculation, if only one question mark expr, return the question mark expression
|
||||
//result directly, even if it is a param array, this is to avoid constructing a param array
|
||||
//in the pre calculation
|
||||
if (OB_FAIL(ObSqlExpressionUtil::expand_array_params(expr_ctx, *value, value))) {
|
||||
LOG_WARN("expand array params failed", K(ret), KPC(value));
|
||||
}
|
||||
@ -371,7 +384,7 @@ int ObPostfixExpression::calc(common::ObExprCtx& expr_ctx, const common::ObNewRo
|
||||
result_val = *value;
|
||||
}
|
||||
} else if (OB_UNLIKELY(post_exprs_.at(last_idx).get_item_type() == T_OP_SHADOW_UK_PROJECT)) {
|
||||
// fast pass for shadow unique key project
|
||||
//对于shadow unique key project表达式走优化路径
|
||||
if (OB_FAIL(uk_fast_project(expr_ctx, row, result_val))) {
|
||||
LOG_WARN("fail to do uk fast project", K(ret));
|
||||
}
|
||||
@ -388,8 +401,9 @@ int ObPostfixExpression::calc(common::ObExprCtx& expr_ctx, const common::ObNewRo
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPostfixExpression::calc(
|
||||
common::ObExprCtx& expr_ctx, const common::ObNewRow& row1, const common::ObNewRow& row2, ObObj& result_val) const
|
||||
int ObPostfixExpression::calc(common::ObExprCtx &expr_ctx, const common::ObNewRow &row1,
|
||||
const common::ObNewRow &row2,
|
||||
ObObj &result_val) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObNewRow result_row;
|
||||
@ -403,7 +417,7 @@ int ObPostfixExpression::calc(
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline int ObPostfixExpression::uk_fast_project(ObExprCtx& expr_ctx, const ObNewRow& row, ObObj& result_val) const
|
||||
inline int ObPostfixExpression::uk_fast_project(ObExprCtx &expr_ctx, const ObNewRow &row, ObObj &result_val) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t expr_cnt = post_exprs_.count();
|
||||
@ -425,18 +439,15 @@ inline int ObPostfixExpression::uk_fast_project(ObExprCtx& expr_ctx, const ObNew
|
||||
}
|
||||
}
|
||||
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 = post_exprs_.at(unique_key_cnt);
|
||||
const ObPostExprItem &item = post_exprs_.at(unique_key_cnt);
|
||||
if (!expr_ctx.row_ctx_.is_uk_cnt_null_) {
|
||||
result_val.set_null();
|
||||
} else if (OB_UNLIKELY(item.get_item_type() != T_REF_COLUMN)) {
|
||||
@ -455,13 +466,14 @@ inline int ObPostfixExpression::uk_fast_project(ObExprCtx& expr_ctx, const ObNew
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPostfixExpression::calc_result_row(ObExprCtx& expr_ctx, const common::ObNewRow& row, ObNewRow& result_row) const
|
||||
int ObPostfixExpression::calc_result_row(ObExprCtx &expr_ctx, const common::ObNewRow &row,
|
||||
ObNewRow &result_row) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
// fast path for single ref column or question mark.
|
||||
if (1 == post_exprs_.count() &&
|
||||
(post_exprs_[0].get_item_type() == T_REF_COLUMN || post_exprs_[0].get_item_type() == T_QUESTIONMARK)) {
|
||||
const ObPostExprItem& item = post_exprs_[0];
|
||||
if (1 == post_exprs_.count()
|
||||
&& (post_exprs_[0].get_item_type() == T_REF_COLUMN || post_exprs_[0].get_item_type() == T_QUESTIONMARK)) {
|
||||
const ObPostExprItem &item = post_exprs_[0];
|
||||
if (item.get_item_type() == T_REF_COLUMN) {
|
||||
int64_t idx = item.get_column();
|
||||
if (OB_UNLIKELY(idx < 0 || idx >= row.count_)) {
|
||||
@ -470,14 +482,14 @@ int ObPostfixExpression::calc_result_row(ObExprCtx& expr_ctx, const common::ObNe
|
||||
} else {
|
||||
result_row.cells_[0] = row.cells_[idx];
|
||||
}
|
||||
} else { // T_QUESTIONMARK
|
||||
const ObObj* obj = NULL;
|
||||
} else { // T_QUESTIONMARK
|
||||
const ObObj *obj = NULL;
|
||||
if (OB_FAIL(item.get_indirect_const(*expr_ctx.phy_plan_ctx_, obj))) {
|
||||
LOG_WARN("fail to get obj", K(ret));
|
||||
} else if (!expr_ctx.is_pre_calculation_) {
|
||||
// in pre calculation, if only one question mark expr, return the question mark expression
|
||||
// result directly, even if it is a param array, this is to avoid constructing a param array
|
||||
// in the pre calculation
|
||||
//in pre calculation, if only one question mark expr, return the question mark expression
|
||||
//result directly, even if it is a param array, this is to avoid constructing a param array
|
||||
//in the pre calculation
|
||||
if (OB_FAIL(ObSqlExpressionUtil::expand_array_params(expr_ctx, *obj, obj))) {
|
||||
LOG_WARN("expand array params failed", K(ret), KPC(obj));
|
||||
}
|
||||
@ -492,10 +504,12 @@ int ObPostfixExpression::calc_result_row(ObExprCtx& expr_ctx, const common::ObNe
|
||||
expr_ctx.infix_expr_ = NULL;
|
||||
|
||||
int64_t idx = 0;
|
||||
static RLOCAL(int64_t, stack_top);
|
||||
RLOCAL(int64_t, stack_top);
|
||||
//在每次计算的开始,应该保留栈的开始位置,如果计算是正常结束,计算栈里面的值会自然的被弹空
|
||||
//但是如果计算是异常退出,压栈的元素不能被弹出,需要在退出的时候将栈置为开始的位置,不然会导致栈异常增长
|
||||
int64_t stack_start = stack_top;
|
||||
ObObj* stack = NULL;
|
||||
auto* the_stack = GET_TSI_MULT(ObPostfixExpressionCalcStack, 1);
|
||||
ObObj *stack = NULL;
|
||||
auto *the_stack = GET_TSI_MULT(ObPostfixExpressionCalcStack, 1);
|
||||
if (OB_ISNULL(the_stack)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_ERROR("no memory", K(ret));
|
||||
@ -513,7 +527,7 @@ int ObPostfixExpression::calc_result_row(ObExprCtx& expr_ctx, const common::ObNe
|
||||
ret = OB_SIZE_OVERFLOW;
|
||||
LOG_WARN("calculation stack overflow", K(+stack_top), K(idx), K(expr_len));
|
||||
} else {
|
||||
const ObPostExprItem& item = post_exprs_[idx];
|
||||
const ObPostExprItem &item = post_exprs_[idx];
|
||||
switch (item.get_item_type()) {
|
||||
case T_OP_AGG_PARAM_LIST: {
|
||||
if (OB_FAIL(calc_agg_param_list(result_row, item, stack, stack_top))) {
|
||||
@ -539,20 +553,16 @@ int ObPostfixExpression::calc_result_row(ObExprCtx& expr_ctx, const common::ObNe
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // end switch
|
||||
} // end else
|
||||
} // end for
|
||||
} // end switch
|
||||
} // end else
|
||||
} // end for
|
||||
|
||||
if (OB_SUCC(ret) && ObMaxType == result_row.cells_[0].get_type()) {
|
||||
if (OB_UNLIKELY(idx != expr_len || stack_top <= 0 || 1 != result_row.count_ || 1 != output_column_count_)) {
|
||||
if (OB_UNLIKELY(idx != expr_len || stack_top <= 0
|
||||
|| 1 != result_row.count_ || 1 != output_column_count_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("idx not equal to expr_len, or stack top less than 0, or cell or column count is not 1",
|
||||
K(ret),
|
||||
K(idx),
|
||||
K(expr_len),
|
||||
K(+stack_top),
|
||||
K(result_row.count_),
|
||||
K_(output_column_count));
|
||||
K(ret), K(idx), K(expr_len), K(+stack_top), K(result_row.count_), K_(output_column_count));
|
||||
} else {
|
||||
result_row.cells_[0] = stack[--stack_top];
|
||||
}
|
||||
@ -563,15 +573,17 @@ int ObPostfixExpression::calc_result_row(ObExprCtx& expr_ctx, const common::ObNe
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPostfixExpression::calc_result_row(
|
||||
ObExprCtx& expr_ctx, const common::ObNewRow& row1, const common::ObNewRow& row2, ObNewRow& result_row) const
|
||||
int ObPostfixExpression::calc_result_row(ObExprCtx &expr_ctx, const common::ObNewRow &row1,
|
||||
const common::ObNewRow &row2, ObNewRow &result_row) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t idx = 0;
|
||||
static RLOCAL(int64_t, stack_top);
|
||||
RLOCAL(int64_t, stack_top);
|
||||
//在每次计算的开始,应该保留栈的开始位置,如果计算是正常结束,计算栈里面的值会自然的被弹空
|
||||
//但是如果计算是异常退出,压栈的元素不能被弹出,需要在退出的时候将栈置为开始的位置,不然会导致栈异常增长
|
||||
int64_t stack_start = stack_top;
|
||||
ObObj* stack = NULL;
|
||||
auto* the_stack = GET_TSI_MULT(ObPostfixExpressionCalcStack, 2);
|
||||
ObObj *stack = NULL;
|
||||
auto *the_stack = GET_TSI_MULT(ObPostfixExpressionCalcStack, 2);
|
||||
if (OB_ISNULL(the_stack)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_ERROR("no memory");
|
||||
@ -594,7 +606,7 @@ int ObPostfixExpression::calc_result_row(
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("calculation stack overflow", K(+stack_top), K(idx), K(expr_len));
|
||||
} else {
|
||||
const ObPostExprItem& item = post_exprs_[idx];
|
||||
const ObPostExprItem &item = post_exprs_[idx];
|
||||
switch (item.get_item_type()) {
|
||||
case T_OP_AGG_PARAM_LIST: {
|
||||
if (OB_FAIL(calc_agg_param_list(result_row, item, stack, stack_top))) {
|
||||
@ -620,20 +632,16 @@ int ObPostfixExpression::calc_result_row(
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // end switch
|
||||
} // end of else
|
||||
} // end of for
|
||||
} // end switch
|
||||
}//end of else
|
||||
}//end of for
|
||||
|
||||
if (OB_SUCC(ret) && ObMaxType == result_row.cells_[0].get_type()) {
|
||||
if (OB_UNLIKELY(idx != expr_len || stack_top <= 0 || 1 != result_row.count_ || 1 != output_column_count_)) {
|
||||
if (OB_UNLIKELY(idx != expr_len || stack_top <= 0
|
||||
|| 1 != result_row.count_ || 1 != output_column_count_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("idx not equal to expr_len, or stack top less than 0, or cell or column count is not 1",
|
||||
K(ret),
|
||||
K(idx),
|
||||
K(expr_len),
|
||||
K(+stack_top),
|
||||
K(result_row.count_),
|
||||
K_(output_column_count));
|
||||
K(ret), K(idx), K(expr_len), K(+stack_top), K(result_row.count_), K_(output_column_count));
|
||||
} else {
|
||||
result_row.cells_[0] = stack[--stack_top];
|
||||
}
|
||||
@ -643,35 +651,30 @@ int ObPostfixExpression::calc_result_row(
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_INLINE int ObPostfixExpression::calc_agg_param_list(
|
||||
ObNewRow& result_row, const ObPostExprItem& item, ObObj* stack, int64_t stack_top) const
|
||||
OB_INLINE int ObPostfixExpression::calc_agg_param_list(ObNewRow &result_row,
|
||||
const ObPostExprItem &item,
|
||||
ObObj *stack, int64_t stack_top) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObExprOperator* agg_param_list = item.get_expr_operator();
|
||||
if (OB_ISNULL(stack) || OB_ISNULL(agg_param_list) || OB_ISNULL(result_row.cells_) ||
|
||||
OB_UNLIKELY(stack_top < 0 || stack_top >= ObPostfixExpressionCalcStack::STACK_SIZE)) {
|
||||
//根据dimension取出栈中的元素填充到result_row中
|
||||
const ObExprOperator *agg_param_list = item.get_expr_operator();
|
||||
if (OB_ISNULL(stack) || OB_ISNULL(agg_param_list) || OB_ISNULL(result_row.cells_)
|
||||
|| OB_UNLIKELY(stack_top < 0 || stack_top >= ObPostfixExpressionCalcStack::STACK_SIZE)) {
|
||||
ret = OB_BAD_NULL_ERROR;
|
||||
LOG_WARN("something is null, or stack_top out of range",
|
||||
K(ret),
|
||||
K(stack),
|
||||
K(agg_param_list),
|
||||
K_(result_row.cells),
|
||||
K(stack_top));
|
||||
K(ret), K(stack), K(agg_param_list), K_(result_row.cells), K(stack_top));
|
||||
} else {
|
||||
int32_t param_num = agg_param_list->get_real_param_num() * agg_param_list->get_row_dimension();
|
||||
if (OB_UNLIKELY(
|
||||
!(&item == &post_exprs_.at(post_exprs_.count() - 1) && T_OP_AGG_PARAM_LIST == agg_param_list->get_type() &&
|
||||
ObExprOperator::NOT_ROW_DIMENSION != agg_param_list->get_row_dimension() && param_num <= stack_top &&
|
||||
param_num == result_row.count_ && param_num == output_column_count_))) {
|
||||
if (OB_UNLIKELY(!(&item == &post_exprs_.at(post_exprs_.count() - 1)
|
||||
&& T_OP_AGG_PARAM_LIST == agg_param_list->get_type()
|
||||
&& ObExprOperator::NOT_ROW_DIMENSION != agg_param_list->get_row_dimension()
|
||||
&& param_num <= stack_top
|
||||
&& param_num == result_row.count_
|
||||
&& param_num == output_column_count_))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("something is invalid",
|
||||
K(ret),
|
||||
K(agg_param_list->get_type()),
|
||||
K(agg_param_list->get_row_dimension()),
|
||||
K(param_num),
|
||||
K(stack_top),
|
||||
K_(result_row.count),
|
||||
K_(output_column_count));
|
||||
LOG_WARN("something is invalid", K(ret),
|
||||
K(agg_param_list->get_type()), K(agg_param_list->get_row_dimension()),
|
||||
K(param_num), K(stack_top), K_(result_row.count), K_(output_column_count));
|
||||
} else {
|
||||
for (int64_t i = 0, j = stack_top - param_num; OB_SUCC(ret) && i < param_num; ++i, ++j) {
|
||||
result_row.cells_[i] = stack[j];
|
||||
@ -681,27 +684,25 @@ OB_INLINE int ObPostfixExpression::calc_agg_param_list(
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_INLINE int ObPostfixExpression::calc_ref_column(
|
||||
const ObNewRow& row, ObNewRow& result_row, const ObPostExprItem& item, ObObj* stack, int64_t& stack_top) const
|
||||
|
||||
OB_INLINE int ObPostfixExpression::calc_ref_column(const ObNewRow &row,
|
||||
ObNewRow &result_row, const ObPostExprItem &item,
|
||||
ObObj *stack, int64_t &stack_top) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t cell_idx = item.get_column();
|
||||
if (OB_ISNULL(stack) || OB_ISNULL(row.cells_) || OB_ISNULL(result_row.cells_) ||
|
||||
OB_UNLIKELY(stack_top < 0 || stack_top >= ObPostfixExpressionCalcStack::STACK_SIZE)) {
|
||||
if (OB_ISNULL(stack) || OB_ISNULL(row.cells_) || OB_ISNULL(result_row.cells_)
|
||||
|| OB_UNLIKELY(stack_top < 0 || stack_top >= ObPostfixExpressionCalcStack::STACK_SIZE)) {
|
||||
ret = OB_BAD_NULL_ERROR;
|
||||
LOG_WARN("something is null, or stack_top out of range",
|
||||
K(ret),
|
||||
K(stack),
|
||||
K_(row.cells),
|
||||
K_(result_row.cells),
|
||||
K(stack_top));
|
||||
K(ret), K(stack), K_(row.cells), K_(result_row.cells), K(stack_top));
|
||||
} else if (OB_UNLIKELY(cell_idx < 0 || cell_idx >= row.count_)) {
|
||||
ret = OB_ARRAY_OUT_OF_RANGE;
|
||||
LOG_WARN("cell_index out of range", K(ret), K(cell_idx), K_(row.count));
|
||||
} else {
|
||||
stack[stack_top] = row.cells_[cell_idx];
|
||||
if (OB_UNLIKELY(ObBitType == row.cells_[cell_idx].get_type())) {
|
||||
// use object scale to store bit length
|
||||
//use object scale to store bit length
|
||||
stack[stack_top].set_scale(item.get_accuracy().get_precision());
|
||||
} else if (-1 != item.get_accuracy().get_scale()) {
|
||||
stack[stack_top].set_scale(item.get_accuracy().get_scale());
|
||||
@ -711,26 +712,23 @@ OB_INLINE int ObPostfixExpression::calc_ref_column(
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_INLINE int ObPostfixExpression::calc_ref_column(const ObNewRow& row1, const ObNewRow& row2, ObNewRow& result_row,
|
||||
const ObPostExprItem& item, ObObj* stack, int64_t& stack_top) const
|
||||
OB_INLINE int ObPostfixExpression::calc_ref_column(const ObNewRow &row1, const ObNewRow &row2,
|
||||
ObNewRow &result_row, const ObPostExprItem &item,
|
||||
ObObj *stack, int64_t &stack_top) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t cell_idx = item.get_column();
|
||||
if (OB_ISNULL(stack) || OB_ISNULL(row1.cells_) || OB_ISNULL(row2.cells_) || OB_ISNULL(result_row.cells_) ||
|
||||
OB_UNLIKELY(stack_top < 0 || stack_top >= ObPostfixExpressionCalcStack::STACK_SIZE)) {
|
||||
if (OB_ISNULL(stack) || OB_ISNULL(row1.cells_) || OB_ISNULL(row2.cells_) ||
|
||||
OB_ISNULL(result_row.cells_)
|
||||
|| OB_UNLIKELY(stack_top < 0 || stack_top >= ObPostfixExpressionCalcStack::STACK_SIZE)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("something is null, or stack_top out of range",
|
||||
K(ret),
|
||||
K(stack),
|
||||
K_(row1.cells),
|
||||
K_(row2.cells),
|
||||
K_(result_row.cells),
|
||||
K(stack_top));
|
||||
K(ret), K(stack), K_(row1.cells), K_(row2.cells), K_(result_row.cells), K(stack_top));
|
||||
} else if (OB_UNLIKELY(cell_idx < 0 || cell_idx >= row1.count_ + row2.count_)) {
|
||||
ret = OB_ARRAY_OUT_OF_RANGE;
|
||||
LOG_WARN("cell_index out of range", K(ret), K(cell_idx), K_(row1.count), K_(row2.count));
|
||||
} else {
|
||||
ObObj& obj = (cell_idx < row1.count_) ? row1.cells_[cell_idx] : row2.cells_[cell_idx - row1.count_];
|
||||
ObObj &obj = (cell_idx < row1.count_) ? row1.cells_[cell_idx] : row2.cells_[cell_idx - row1.count_];
|
||||
if (1 == post_exprs_.count()) {
|
||||
if (OB_UNLIKELY(!(1 == result_row.count_ && 1 == output_column_count_))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
@ -741,7 +739,7 @@ OB_INLINE int ObPostfixExpression::calc_ref_column(const ObNewRow& row1, const O
|
||||
} else {
|
||||
stack[stack_top] = obj;
|
||||
if (OB_UNLIKELY(ObBitType == obj.get_type())) {
|
||||
// use object scale to store bit length
|
||||
//use object scale to store bit length
|
||||
stack[stack_top++].set_scale(item.get_accuracy().get_precision());
|
||||
} else {
|
||||
stack[stack_top++].set_scale(item.get_accuracy().get_scale());
|
||||
@ -751,20 +749,19 @@ OB_INLINE int ObPostfixExpression::calc_ref_column(const ObNewRow& row1, const O
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_INLINE int ObPostfixExpression::calc_question_mark(
|
||||
ObExprCtx& expr_ctx, ObNewRow& result_row, const ObPostExprItem& item, ObObj* stack, int64_t& stack_top) const
|
||||
OB_INLINE int ObPostfixExpression::calc_question_mark(ObExprCtx &expr_ctx,
|
||||
ObNewRow &result_row,
|
||||
const ObPostExprItem &item,
|
||||
ObObj *stack,
|
||||
int64_t &stack_top) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObObj* obj = NULL;
|
||||
if (OB_ISNULL(stack) || OB_ISNULL(result_row.cells_) || OB_ISNULL(expr_ctx.phy_plan_ctx_) ||
|
||||
OB_UNLIKELY(stack_top < 0 || stack_top >= ObPostfixExpressionCalcStack::STACK_SIZE)) {
|
||||
const ObObj *obj = NULL;
|
||||
if (OB_ISNULL(stack) || OB_ISNULL(result_row.cells_) || OB_ISNULL(expr_ctx.phy_plan_ctx_)
|
||||
|| OB_UNLIKELY(stack_top < 0 || stack_top >= ObPostfixExpressionCalcStack::STACK_SIZE)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("something is null, or stack_top out of range",
|
||||
K(ret),
|
||||
K(stack),
|
||||
K_(result_row.cells),
|
||||
K(stack_top),
|
||||
K_(expr_ctx.phy_plan_ctx));
|
||||
K(ret), K(stack), K_(result_row.cells), K(stack_top), K_(expr_ctx.phy_plan_ctx));
|
||||
} else if (OB_FAIL(item.get_indirect_const(*expr_ctx.phy_plan_ctx_, obj))) {
|
||||
LOG_WARN("failed to get value obj", K(ret));
|
||||
} else if (OB_FAIL(ObSqlExpressionUtil::expand_array_params(expr_ctx, *obj, obj))) {
|
||||
@ -776,8 +773,8 @@ OB_INLINE int ObPostfixExpression::calc_question_mark(
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_INLINE int ObPostfixExpression::calc_other_op(
|
||||
ObExprCtx& expr_ctx, const ObPostExprItem& item, ObObj* stack, int64_t& stack_top) const
|
||||
OB_INLINE int ObPostfixExpression::calc_other_op(ObExprCtx &expr_ctx, const ObPostExprItem &item,
|
||||
ObObj *stack, int64_t &stack_top) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(stack)) {
|
||||
@ -787,12 +784,13 @@ OB_INLINE int ObPostfixExpression::calc_other_op(
|
||||
stack[stack_top] = item.get_obj();
|
||||
stack_top++;
|
||||
} else if (IS_EXPR_OP(item.get_item_type())) {
|
||||
const ObExprOperator* expr_op = item.get_expr_operator();
|
||||
const ObExprOperator *expr_op = item.get_expr_operator();
|
||||
if (OB_ISNULL(expr_op)) {
|
||||
ret = OB_BAD_NULL_ERROR;
|
||||
LOG_WARN("expr_op is null", K(ret), K(item.get_item_type()));
|
||||
} else if (OB_FAIL(expr_op->call(stack, stack_top, expr_ctx))) {
|
||||
LOG_WARN("failed to call expr operator", K(ret), "expr_name", item.get_expr_operator()->get_name(), K(item));
|
||||
LOG_WARN("failed to call expr operator", K(ret),
|
||||
"expr_name", item.get_expr_operator()->get_name(), K(item));
|
||||
}
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
@ -801,13 +799,15 @@ OB_INLINE int ObPostfixExpression::calc_other_op(
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ObPostfixExpression::is_equijoin_cond(
|
||||
int64_t& c1, int64_t& c2, ObObjType& cmp_type, ObCollationType& cmp_cs_type, bool& is_null_safe) const
|
||||
bool ObPostfixExpression::is_equijoin_cond(int64_t &c1, int64_t &c2,
|
||||
ObObjType &cmp_type, ObCollationType &cmp_cs_type,
|
||||
bool &is_null_safe) const
|
||||
{
|
||||
bool ret = false;
|
||||
if (post_exprs_.count() == 3) {
|
||||
if ((post_exprs_[2].get_item_type() == T_OP_EQ || post_exprs_[2].get_item_type() == T_OP_NSEQ) &&
|
||||
post_exprs_[1].get_item_type() == T_REF_COLUMN && post_exprs_[0].get_item_type() == T_REF_COLUMN) {
|
||||
if ((post_exprs_[2].get_item_type() == T_OP_EQ || post_exprs_[2].get_item_type() == T_OP_NSEQ)
|
||||
&& post_exprs_[1].get_item_type() == T_REF_COLUMN
|
||||
&& post_exprs_[0].get_item_type() == T_REF_COLUMN) {
|
||||
c1 = post_exprs_[0].get_column();
|
||||
c2 = post_exprs_[1].get_column();
|
||||
cmp_type = post_exprs_[2].get_expr_operator()->get_result_type().get_calc_type();
|
||||
@ -847,7 +847,7 @@ DEFINE_DESERIALIZE(ObPostfixExpression)
|
||||
} else if (OB_FAIL(post_exprs_.push_back(item))) {
|
||||
LOG_WARN("failed to push into array", K(ret));
|
||||
}
|
||||
} // end for
|
||||
} // end for
|
||||
OB_UNIS_DECODE(output_column_count_);
|
||||
}
|
||||
}
|
||||
@ -863,7 +863,7 @@ DEFINE_GET_SERIALIZE_SIZE(ObPostfixExpression)
|
||||
return len;
|
||||
}
|
||||
|
||||
int64_t ObPostfixExpression::to_string(char* buf, const int64_t buf_len) const
|
||||
int64_t ObPostfixExpression::to_string(char *buf, const int64_t buf_len) const
|
||||
{
|
||||
int64_t pos = 0;
|
||||
J_ARRAY_START();
|
||||
@ -872,9 +872,9 @@ int64_t ObPostfixExpression::to_string(char* buf, const int64_t buf_len) const
|
||||
J_COMMA();
|
||||
}
|
||||
BUF_PRINTO(post_exprs_[i]);
|
||||
} // end for
|
||||
} // end for
|
||||
J_ARRAY_END();
|
||||
return pos;
|
||||
}
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user