提交 2c4f8593 编写于 作者: O obdev 提交者: wangzelin.wzl

Fix atan does not support two parameters in mysql mode

上级 ce63c892
......@@ -709,7 +709,12 @@ int ObMPStmtExecute::do_process(
bool first_record = (0 == audit_record.try_cnt_);
ObExecStatUtils::record_exec_timestamp(*this, first_record, audit_record.exec_timestamp_);
}
if (OB_FAIL(ret) && !async_resp_used && need_response_error && conn_valid_ && !THIS_WORKER.need_retry()) {
if (OB_FAIL(ret)
&& !async_resp_used
&& need_response_error
&& conn_valid_
&& !THIS_WORKER.need_retry()
&& !retry_ctrl_.need_retry()) {
LOG_WARN("query failed", K(ret), K(retry_ctrl_.need_retry()), K_(stmt_id));
bool is_partition_hit = session.partition_hit().get_bool();
int err = send_error_packet(ret, NULL, is_partition_hit, (void*)(&ctx_.reroute_info_));
......
......@@ -22,50 +22,147 @@
using namespace oceanbase::common;
using namespace oceanbase::sql;
namespace oceanbase {
namespace sql {
ObExprAtan::ObExprAtan(ObIAllocator& alloc) : ObFuncExprOperator(alloc, T_FUN_SYS_ATAN, N_ATAN, 1, NOT_ROW_DIMENSION)
{}
namespace oceanbase
{
namespace sql
{
ObExprAtan::ObExprAtan(ObIAllocator &alloc)
: ObFuncExprOperator(alloc, T_FUN_SYS_ATAN, N_ATAN, ONE_OR_TWO, NOT_ROW_DIMENSION)
{
}
ObExprAtan::~ObExprAtan()
{}
int ObExprAtan::calc_result_type1(ObExprResType& type, ObExprResType& type1, common::ObExprTypeCtx& type_ctx) const
int ObExprAtan::calc_result_typeN(ObExprResType &type,
ObExprResType *types,
int64_t type_num,
common::ObExprTypeCtx &type_ctx) const
{
return calc_trig_function_result_type1(type, type1, type_ctx);
int ret = OB_SUCCESS;
if (share::is_oracle_mode() && OB_UNLIKELY(NULL == types || type_num != 1)) {
ret = OB_ERR_PARAM_SIZE;
LOG_WARN("Invalid argument.", K(ret), K(types), K(type_num));
} else if (share::is_mysql_mode()
&& OB_UNLIKELY(NULL == types || type_num <= 0 || type_num > 2)) {
ret = OB_ERR_PARAM_SIZE;
LOG_WARN("Invalid argument.", K(ret), K(types), K(type_num));
} else {
if (1 == type_num) {
ret = calc_trig_function_result_type1(type, types[0], type_ctx);
} else {
ret = calc_trig_function_result_type2(type, types[0], types[1], type_ctx);
}
}
return ret;
}
int ObExprAtan::calc_result1(ObObj& result, const ObObj& obj, ObExprCtx& expr_ctx) const
int ObExprAtan::calc_resultN(common::ObObj &result,
const common::ObObj *objs,
int64_t param_num,
common::ObExprCtx &expr_ctx) const
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(OB_ISNULL(expr_ctx.calc_buf_))) {
if (share::is_oracle_mode() && OB_UNLIKELY(NULL == objs || param_num != 1)) {
ret = OB_ERR_PARAM_SIZE;
LOG_WARN("Invalid argument.", K(ret), K(objs), K(param_num));
} else if (share::is_mysql_mode()
&& OB_UNLIKELY(NULL == objs || param_num <= 0 || param_num > 2)) {
ret = OB_ERR_PARAM_SIZE;
LOG_WARN("Invalid argument.", K(ret), K(objs), K(param_num));
} else if (OB_UNLIKELY(OB_ISNULL(expr_ctx.calc_buf_))) {
ret = OB_NOT_INIT;
LOG_WARN("varchar buffer not init", K(ret));
} else if (OB_UNLIKELY(obj.is_null())) {
result.set_null();
} else if (obj.is_number()) {
number::ObNumber res_nmb;
if (OB_FAIL(obj.get_number().atan(res_nmb, *(expr_ctx.calc_buf_)))) {
LOG_WARN("fail to calc atan", K(obj), K(ret), K(res_nmb));
} else {
result.set_number(res_nmb);
} else {
if (1 == param_num) {
if (objs[0].is_null()) {
result.set_null();
} else if (objs[0].is_number()) {
number::ObNumber res_nmb;
if (OB_FAIL(objs[0].get_number().atan(res_nmb, *(expr_ctx.calc_buf_)))) {
LOG_WARN("fail to calc atan", K(ret), K(res_nmb));
} else {
result.set_number(res_nmb);
}
} else if (objs[0].is_double()) {
double arg = objs[0].get_double();
double res = atan(arg);
result.set_double(res);
}
} else if (2 == param_num) {
// only mysql mode
const ObObj &obj1 = objs[0];
const ObObj &obj2 = objs[1];
if (OB_UNLIKELY(ObNullType == obj1.get_type() || ObNullType == obj2.get_type())) {
result.set_null();
} else {
double arg1 = obj1.get_double();
double arg2 = obj2.get_double();
double res = atan2(arg1, arg2);
result.set_double(res);
}
}
} else if (obj.is_double()) {
double arg = obj.get_double();
double res = atan(arg);
result.set_double(res);
}
return ret;
}
DEF_CALC_TRIGONOMETRIC_EXPR(atan, false, OB_SUCCESS);
int calc_atan_expr(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res_datum)
{
int ret = OB_SUCCESS;
if (1 == expr.arg_cnt_) {
ObDatum *radian = NULL;
if (OB_FAIL(expr.args_[0]->eval(ctx, radian))) {
LOG_WARN("eval radian arg failed", K(ret), K(expr));
} else if (radian->is_null()) {
res_datum.set_null();
} else if (ObNumberType == expr.args_[0]->datum_meta_.type_) {
number::ObNumber res_nmb;
number::ObNumber nmb(radian->get_number());
if (OB_FAIL(nmb.atan(res_nmb, ctx.get_reset_tmp_alloc()))) {
LOG_WARN("fail to calc atan", K(ret), K(res_nmb));
} else {
res_datum.set_number(res_nmb);
}
} else if (ObDoubleType == expr.args_[0]->datum_meta_.type_) {
const double arg = radian->get_double();
res_datum.set_double(atan(arg));
}
} else { // 2 == expr.arg_cnt_
// only mysql mode
ObExpr *arg0 = expr.args_[0];
ObExpr *arg1 = expr.args_[1];
ObDatum *y = NULL;
ObDatum *x = NULL;
if (OB_FAIL(arg0->eval(ctx, y)) || OB_FAIL(arg1->eval(ctx, x))) {
LOG_WARN("eval arg failed", K(ret), K(expr), KP(y), KP(x));
} else if (y->is_null() || x->is_null()) {
/* arg is already be cast to number type, no need to is_null_oracle */
res_datum.set_null();
} else if (ObDoubleType == arg0->datum_meta_.type_
&& ObDoubleType == arg1->datum_meta_.type_) {
res_datum.set_double(atan2(y->get_double(), x->get_double()));
} else {
ret = OB_ERR_UNEXPECTED;
}
}
return ret;
}
int ObExprAtan::cg_expr(ObExprCGCtx& expr_cg_ctx, const ObRawExpr& raw_expr, ObExpr& rt_expr) const
{
int ret = OB_SUCCESS;
UNUSED(expr_cg_ctx);
UNUSED(raw_expr);
rt_expr.eval_func_ = calc_atan_expr;
if (share::is_oracle_mode() && OB_UNLIKELY(1 != rt_expr.arg_cnt_)) {
ret = OB_ERR_PARAM_SIZE;
LOG_WARN("invalid arg cnt of expr", K(ret), K(rt_expr));
} else if (share::is_mysql_mode()
&& OB_UNLIKELY(1 != rt_expr.arg_cnt_ && 2 != rt_expr.arg_cnt_)) {
ret = OB_ERR_PARAM_SIZE;
LOG_WARN("invalid arg cnt of expr", K(ret), K(rt_expr));
} else {
rt_expr.eval_func_ = calc_atan_expr;
}
return ret;
}
......
......@@ -20,10 +20,16 @@ class ObExprAtan : public ObFuncExprOperator {
public:
explicit ObExprAtan(common::ObIAllocator& alloc);
virtual ~ObExprAtan();
virtual int calc_result_type1(ObExprResType& type, ObExprResType& type1, common::ObExprTypeCtx& type_ctx) const;
virtual int calc_result1(common::ObObj& result, const common::ObObj& obj, common::ObExprCtx& expr_ctx) const;
virtual int cg_expr(ObExprCGCtx& expr_cg_ctx, const ObRawExpr& raw_expr, ObExpr& rt_expr) const override;
virtual int calc_result_typeN(ObExprResType &type,
ObExprResType *types,
int64_t type_num,
common::ObExprTypeCtx &type_ctx) const;
virtual int calc_resultN(common::ObObj &result,
const common::ObObj *objs,
int64_t param_num,
common::ObExprCtx &expr_ctx) const;
virtual int cg_expr(ObExprCGCtx &expr_cg_ctx, const ObRawExpr &raw_expr,
ObExpr &rt_expr) const override;
private:
DISALLOW_COPY_AND_ASSIGN(ObExprAtan);
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册