From 889d5cb6d8c804ad8e78d9ca101f95cced4f5b90 Mon Sep 17 00:00:00 2001 From: ls0 Date: Wed, 21 Jul 2021 18:01:16 +0800 Subject: [PATCH] implement expr asin/acos/cot/cos in mysql mode --- deps/oblib/src/lib/ob_name_def.h | 1 + src/sql/CMakeLists.txt | 1 + src/sql/engine/expr/ob_expr_acos.cpp | 2 +- src/sql/engine/expr/ob_expr_asin.cpp | 2 +- src/sql/engine/expr/ob_expr_cot.cpp | 70 +++++++++++++++++++ src/sql/engine/expr/ob_expr_cot.h | 35 ++++++++++ src/sql/engine/expr/ob_expr_operator.cpp | 2 +- .../engine/expr/ob_expr_operator_factory.cpp | 5 ++ src/sql/engine/expr/ob_expr_util.h | 2 +- src/sql/parser/ob_item_type.h | 2 +- src/sql/parser/type_name.c | 1 + 11 files changed, 118 insertions(+), 5 deletions(-) create mode 100644 src/sql/engine/expr/ob_expr_cot.cpp create mode 100644 src/sql/engine/expr/ob_expr_cot.h diff --git a/deps/oblib/src/lib/ob_name_def.h b/deps/oblib/src/lib/ob_name_def.h index 5a33c1768..cf7f1dd4f 100644 --- a/deps/oblib/src/lib/ob_name_def.h +++ b/deps/oblib/src/lib/ob_name_def.h @@ -130,6 +130,7 @@ #define N_ACOS "acos" #define N_ATAN "atan" #define N_ATAN2 "atan2" +#define N_COT "cot" #define N_PUMP_ROW_DESC "pump_row_desc" #define N_ROOT_ROW_DESC "root_row_desc" #define N_PSEUDO_COLUMN_ROW_DESC "pseudo_column_row_desc" diff --git a/src/sql/CMakeLists.txt b/src/sql/CMakeLists.txt index 3e4fe608a..31566eb68 100644 --- a/src/sql/CMakeLists.txt +++ b/src/sql/CMakeLists.txt @@ -195,6 +195,7 @@ ob_set_subtarget(ob_sql engine engine/expr/ob_expr_tan.cpp engine/expr/ob_expr_atan.cpp engine/expr/ob_expr_atan2.cpp + engine/expr/ob_expr_cot.cpp engine/expr/ob_expr_between.cpp engine/expr/ob_expr_bit_and.cpp engine/expr/ob_expr_bit_count.cpp diff --git a/src/sql/engine/expr/ob_expr_acos.cpp b/src/sql/engine/expr/ob_expr_acos.cpp index a4f14c275..146bfa5ea 100644 --- a/src/sql/engine/expr/ob_expr_acos.cpp +++ b/src/sql/engine/expr/ob_expr_acos.cpp @@ -52,7 +52,7 @@ int ObExprAcos::calc_result1(ObObj& result, const ObObj& obj, ObExprCtx& expr_ct } else if (obj.is_double()) { double arg = obj.get_double(); if (arg > 1 || arg < -1) { - ret = OB_ERR_ARGUMENT_OUT_OF_RANGE; + result.set_null(); } else { double res = acos(arg); result.set_double(res); diff --git a/src/sql/engine/expr/ob_expr_asin.cpp b/src/sql/engine/expr/ob_expr_asin.cpp index 8dcdc4c13..e4eab232f 100644 --- a/src/sql/engine/expr/ob_expr_asin.cpp +++ b/src/sql/engine/expr/ob_expr_asin.cpp @@ -53,7 +53,7 @@ int ObExprAsin::calc_result1(ObObj& result, const ObObj& obj, ObExprCtx& expr_ct } else if (obj.is_double()) { double arg = obj.get_double(); if (arg > 1 || arg < -1) { - ret = OB_ERR_ARGUMENT_OUT_OF_RANGE; + result.set_null(); } else { double res = asin(arg); result.set_double(res); diff --git a/src/sql/engine/expr/ob_expr_cot.cpp b/src/sql/engine/expr/ob_expr_cot.cpp new file mode 100644 index 000000000..83a963f9b --- /dev/null +++ b/src/sql/engine/expr/ob_expr_cot.cpp @@ -0,0 +1,70 @@ +/** + * Copyright 2014-2016 Alibaba Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * + * Authors: + * zimiao + */ +#define USING_LOG_PREFIX SQL_ENG +#include "sql/parser/ob_item_type.h" +#include "lib/oblog/ob_log.h" +#include "lib/number/ob_number_v2.h" +#include "sql/engine/expr/ob_expr_cot.h" +#include "sql/session/ob_sql_session_info.h" +#include +namespace oceanbase +{ +using namespace common; +using namespace common::number; +namespace sql +{ +ObExprCot::ObExprCot(ObIAllocator &alloc) + : ObFuncExprOperator(alloc, T_FUN_SYS_COT, N_COT, 1, NOT_ROW_DIMENSION) +{ +} +ObExprCot::~ObExprCot() +{ +} +int ObExprCot::calc_result_type1(ObExprResType &type, + ObExprResType &radian, + ObExprTypeCtx &type_ctx) const +{ + return calc_trig_function_result_type1(type, radian, type_ctx); +} +int ObExprCot::calc_result1(ObObj &result, + const ObObj &radian_obj, + ObExprCtx &expr_ctx) const +{ + int ret = OB_SUCCESS; + if (radian_obj.is_null()) { + result.set_null(); + } else if (OB_ISNULL(expr_ctx.calc_buf_)) { + ret = OB_NOT_INIT; + LOG_WARN("expr_ctx.calc_buf_ is NULL", K(ret)); + } else if (radian_obj.is_double()) { + double arg = radian_obj.get_double(); + double tan_out = tan(arg); + // to check tan(arg) is small enough to be zero + if (0.0 == tan_out) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tan(x) is zero", K(ret)); + } else { + double res = 1.0/tan_out; + if (!std::isfinite(res)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tan(x) is like zero", K(ret)); + } else { + result.set_double(res); + } + } + } else { + ret = OB_ERR_UNEXPECTED; + } + return ret; +} +} /* sql */ +} /* oceanbase */ \ No newline at end of file diff --git a/src/sql/engine/expr/ob_expr_cot.h b/src/sql/engine/expr/ob_expr_cot.h new file mode 100644 index 000000000..6e241035b --- /dev/null +++ b/src/sql/engine/expr/ob_expr_cot.h @@ -0,0 +1,35 @@ +/** + * Copyright 2014-2016 Alibaba Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * + * Authors: + * zimiao + */ +#ifndef OCEANBASE_SQL_ENGINE_EXPR_COT_ +#define OCEANBASE_SQL_ENGINE_EXPR_COT_ +#include "sql/engine/expr/ob_expr_operator.h" +namespace oceanbase +{ +namespace sql +{ +class ObExprCot : public ObFuncExprOperator +{ +public: + explicit ObExprCot(common::ObIAllocator &alloc); + virtual ~ObExprCot(); + virtual int calc_result_type1(ObExprResType &type, + ObExprResType &radian, + common::ObExprTypeCtx &type_ctx) const; + virtual int calc_result1(common::ObObj &result, + const common::ObObj &radian_obj, + common::ObExprCtx &expr_ctx) const; +private: + DISALLOW_COPY_AND_ASSIGN(ObExprCot); +}; +} +} +#endif /* OCEANBASE_SQL_ENGINE_EXPR_COT_ */ \ No newline at end of file diff --git a/src/sql/engine/expr/ob_expr_operator.cpp b/src/sql/engine/expr/ob_expr_operator.cpp index b6a389763..50111fe2e 100644 --- a/src/sql/engine/expr/ob_expr_operator.cpp +++ b/src/sql/engine/expr/ob_expr_operator.cpp @@ -1591,7 +1591,7 @@ int ObExprOperator::calc_trig_function_result_type1( type.set_precision(ObAccuracy::DDL_DEFAULT_ACCURACY2[ORACLE_MODE][type.get_type()].get_precision()); } type1.set_calc_type(type.get_type()); - ObExprOperator::calc_result_flag1(type, type1); + //no need add not null check for trig/ln/e funciotn in mysql mode return ret; } diff --git a/src/sql/engine/expr/ob_expr_operator_factory.cpp b/src/sql/engine/expr/ob_expr_operator_factory.cpp index f6b264483..f04d9ba69 100644 --- a/src/sql/engine/expr/ob_expr_operator_factory.cpp +++ b/src/sql/engine/expr/ob_expr_operator_factory.cpp @@ -105,6 +105,7 @@ #include "sql/engine/expr/ob_expr_sinh.h" #include "sql/engine/expr/ob_expr_cosh.h" #include "sql/engine/expr/ob_expr_tanh.h" +#include "sql/engine/expr/ob_expr_cot.h" #include "sql/engine/expr/ob_expr_trim.h" #include "sql/engine/expr/ob_expr_inner_trim.h" #include "sql/engine/expr/ob_expr_unhex.h" @@ -638,6 +639,10 @@ void ObExprOperatorFactory::register_expr_operators() REG_OP(ObExprBool); REG_OP(ObExprSin); REG_OP(ObExprTan); + REG_OP(ObExprCos); + REG_OP(ObExprCot); + REG_OP(ObExprAsin); + REG_OP(ObExprAcos); REG_OP(ObExprCalcPartitionId); REG_OP(ObExprPartIdPseudoColumn); REG_OP(ObExprStmtId); diff --git a/src/sql/engine/expr/ob_expr_util.h b/src/sql/engine/expr/ob_expr_util.h index cef540785..b30ffbdd9 100644 --- a/src/sql/engine/expr/ob_expr_util.h +++ b/src/sql/engine/expr/ob_expr_util.h @@ -145,7 +145,7 @@ T ObExprUtil::trunc_integer(T val, int64_t dec) } else if (ObDoubleType == expr.args_[0]->datum_meta_.type_) { \ const double arg = radian->get_double(); \ if (INVALID_DOUBLE_ARG_CHECK) { \ - ret = INVALID_DOUBLE_ARG_ERRNO; \ + res_datum.set_null(); \ } else { \ res_datum.set_double(tritype(arg)); \ } \ diff --git a/src/sql/parser/ob_item_type.h b/src/sql/parser/ob_item_type.h index 1a49fa2b1..3b87f78e5 100644 --- a/src/sql/parser/ob_item_type.h +++ b/src/sql/parser/ob_item_type.h @@ -422,7 +422,7 @@ typedef enum ObItemType { T_FUN_SYS_MAKETIME = 707, T_FUN_SYS_MONTH_NAME = 708, T_FUN_SYS_FORMAT = 709, - // T_FUN_SYS_COT = 710, 710 has ben taken on master + T_FUN_SYS_COT = 710, T_FUN_SYS_QUARTER = 711, T_FUN_SYS_BIT_LENGTH = 712, T_FUN_SYS_PI = 713, diff --git a/src/sql/parser/type_name.c b/src/sql/parser/type_name.c index beb5a643f..394702953 100644 --- a/src/sql/parser/type_name.c +++ b/src/sql/parser/type_name.c @@ -439,6 +439,7 @@ const char* get_type_name(int type) case T_FUN_SYS_ACOS : return "T_FUN_SYS_ACOS"; case T_FUN_SYS_ATAN : return "T_FUN_SYS_ATAN"; case T_FUN_SYS_ATAN2 : return "T_FUN_SYS_ATAN2"; + case T_FUN_SYS_COT : return "T_FUN_SYS_COT"; case T_FUN_SYS_REGEXP_COUNT : return "T_FUN_SYS_REGEXP_COUNT"; case T_FUN_NVL2 : return "T_FUN_NVL2"; case T_FUN_SYS_TO_BINARY_FLOAT : return "T_FUN_SYS_TO_BINARY_FLOAT";