patch 4.0
This commit is contained in:
@ -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
|
||||
|
||||
Reference in New Issue
Block a user