196 lines
5.9 KiB
C++
196 lines
5.9 KiB
C++
/**
|
|
* Copyright (c) 2021 OceanBase
|
|
* OceanBase CE is licensed under Mulan PubL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
|
* You may obtain a copy of Mulan PubL v2 at:
|
|
* http://license.coscl.org.cn/MulanPubL-2.0
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PubL v2 for more details.
|
|
*/
|
|
|
|
#define USING_LOG_PREFIX SQL_ENG
|
|
|
|
#include "ob_rt_datum_arith.h"
|
|
#include "sql/resolver/expr/ob_raw_expr_util.h"
|
|
#include "sql/engine/ob_exec_context.h"
|
|
|
|
namespace oceanbase
|
|
{
|
|
namespace sql
|
|
{
|
|
|
|
ObRTDatumArith::Item ObRTDatumArith::Item::operator+(const ObRTDatumArith::Item &r)
|
|
{
|
|
return NULL == arith_ ? ObRTDatumArith::Item() : arith_->build_arith_expr(*this, r, T_OP_ADD);
|
|
}
|
|
|
|
ObRTDatumArith::Item ObRTDatumArith::Item::operator-(const ObRTDatumArith::Item &r)
|
|
{
|
|
return NULL == arith_ ? ObRTDatumArith::Item() : arith_->build_arith_expr(*this, r, T_OP_MINUS);
|
|
}
|
|
|
|
ObRTDatumArith::Item ObRTDatumArith::Item::operator*(const ObRTDatumArith::Item &r)
|
|
{
|
|
return NULL == arith_ ? ObRTDatumArith::Item() : arith_->build_arith_expr(*this, r, T_OP_MUL);
|
|
}
|
|
|
|
ObRTDatumArith::Item ObRTDatumArith::Item::operator/(const ObRTDatumArith::Item &r)
|
|
{
|
|
return NULL == arith_ ? ObRTDatumArith::Item() : arith_->build_arith_expr(*this, r, T_OP_DIV);
|
|
}
|
|
|
|
|
|
ObRTDatumArith::ObRTDatumArith(ObExecContext &ctx, ObSQLSessionInfo &session)
|
|
: alloc_("RTDatumArith", OB_MALLOC_NORMAL_BLOCK_SIZE, session.get_effective_tenant_id()),
|
|
exec_ctx_(ctx), session_(session), factory_(alloc_), frame_info_(alloc_),
|
|
eval_ctx_(NULL), expr_(NULL), raw_cols_(alloc_), cols_(alloc_)
|
|
{
|
|
}
|
|
|
|
ObRTDatumArith::~ObRTDatumArith()
|
|
{
|
|
if (NULL != eval_ctx_) {
|
|
eval_ctx_->~ObEvalCtx();
|
|
}
|
|
}
|
|
|
|
int ObRTDatumArith::inner_setup_datum_metas(const ObDatumMeta *metas, int64_t cnt)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
CK(NULL != metas && cnt > 0);
|
|
OZ(raw_cols_.init(cnt));
|
|
for (int64_t i = 0; OB_SUCC(ret) && i < cnt; i++) {
|
|
ObColumnRefRawExpr *col = NULL;
|
|
OZ(factory_.create_raw_expr(T_REF_COLUMN, col));
|
|
CK(NULL != col);
|
|
if (OB_SUCC(ret)) {
|
|
ObExprResType &res_type = const_cast<ObExprResType &>(col->get_result_type());
|
|
res_type.set_type(metas[i].type_);
|
|
res_type.set_collation_type(metas[i].cs_type_);
|
|
res_type.set_scale(metas[i].scale_);
|
|
res_type.set_precision(metas[i].precision_);
|
|
OZ(raw_cols_.push_back(col));
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
ObRTDatumArith::Item ObRTDatumArith::ref(const int64_t input_idx)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
Item item;
|
|
if (input_idx >= 0 && input_idx < raw_cols_.count()) {
|
|
item.expr_ = raw_cols_.at(input_idx);
|
|
item.arith_ = this;
|
|
} else {
|
|
ret = OB_INVALID_INDEX;
|
|
LOG_WARN("invalid ref index", K(ret), K(input_idx), K(raw_cols_.count()));
|
|
}
|
|
return item;
|
|
}
|
|
|
|
ObRTDatumArith::Item ObRTDatumArith::build_arith_expr(const Item &l, const Item &r, ObItemType op)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
Item item;
|
|
if (NULL != l.arith_ && NULL != l.expr_
|
|
&& NULL != r.arith_ && NULL != r.expr_) {
|
|
ObOpRawExpr *expr = NULL;
|
|
OZ(factory_.create_raw_expr(op, expr));
|
|
CK(NULL != expr);
|
|
OZ(expr->add_param_expr(l.expr_));
|
|
OZ(expr->add_param_expr(r.expr_));
|
|
|
|
item.arith_ = this;
|
|
item.expr_ = expr;
|
|
}
|
|
return item;
|
|
}
|
|
|
|
int ObRTDatumArith::generate(const ObRTDatumArith::Item item)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (NULL == item.expr_ || NULL == item.arith_) {
|
|
ret = OB_ALLOCATE_MEMORY_FAILED;
|
|
LOG_WARN("invalid ref index or build arith raw expr failed", K(ret));
|
|
} else {
|
|
CK(exec_ctx_.get_physical_plan_ctx());
|
|
OZ(item.expr_->formalize(&session_));
|
|
|
|
ObStaticEngineExprCG expr_cg(alloc_,
|
|
&session_,
|
|
NULL /* schema_guard */,
|
|
0 /* original_param_cnt*/,
|
|
0 /* param_cnt */,
|
|
exec_ctx_.get_min_cluster_version());
|
|
ObRawExprUniqueSet raw_exprs(false);
|
|
OZ(raw_exprs.append(item.expr_));
|
|
OZ(raw_exprs.append(raw_cols_));
|
|
OZ(expr_cg.generate(raw_exprs, frame_info_));
|
|
|
|
OZ(cols_.init(raw_cols_.count()));
|
|
FOREACH_CNT_X(e, raw_cols_, OB_SUCC(ret)) {
|
|
CK(NULL != (*e)->rt_expr_);
|
|
cols_.push_back((*e)->rt_expr_);
|
|
}
|
|
|
|
if (OB_SUCC(ret)) {
|
|
expr_ = item.expr_->rt_expr_;
|
|
CK(NULL != expr_);
|
|
}
|
|
|
|
char **frames = NULL;
|
|
uint64_t frame_cnt = 0;
|
|
|
|
ObPhysicalPlanCtx *phy_ctx = exec_ctx_.get_physical_plan_ctx();
|
|
OZ(frame_info_.alloc_frame(alloc_,
|
|
phy_ctx->get_param_frame_ptrs(),
|
|
frame_cnt,
|
|
frames));
|
|
CK(NULL != frames);
|
|
if (OB_SUCC(ret)) {
|
|
eval_ctx_ = OB_NEWx(ObEvalCtx, (&alloc_), exec_ctx_);
|
|
OV(NULL != eval_ctx_, OB_ALLOCATE_MEMORY_FAILED);
|
|
if (OB_SUCC(ret)) {
|
|
// overwrite the frames of eval_ctx
|
|
eval_ctx_->frames_ = frames;
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// make the clear evaluate flag function be a static function to avoid abusing.
|
|
static void clear_arith_eval_flag(const ObExpr &expr, ObEvalCtx &ctx)
|
|
{
|
|
if (expr.eval_func_ != NULL) {
|
|
expr.get_eval_info(ctx).clear_evaluated_flag();
|
|
for (int64_t i = 0; i < expr.arg_cnt_; i++) {
|
|
clear_arith_eval_flag(*expr.args_[i], ctx);
|
|
}
|
|
}
|
|
}
|
|
|
|
int ObRTDatumArith::inner_eval(ObDatum *&res, const ObDatum **args, int64_t arg_cnt)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
CK(NULL != eval_ctx_);
|
|
CK(NULL != args && arg_cnt == cols_.count());
|
|
|
|
if (OB_SUCC(ret)) {
|
|
// clear evaluate flags first
|
|
clear_arith_eval_flag(*expr_, *eval_ctx_);
|
|
for (int64_t i = 0; i < arg_cnt; i++) {
|
|
cols_.at(i)->locate_expr_datum(*eval_ctx_) = *args[i];
|
|
}
|
|
OZ(expr_->eval(*eval_ctx_, res));
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
} // end namespace sql
|
|
} // end namespace oceanbase
|