多看、多问、多总结,肯定是可以攻克的。

一、Overview

提出疑问

设计一个类是需要需要考虑什么问题

大纲

二、MVP

2.1 流程图

- 类图

### 2.2 整体流程

  • parser阶段 :func(arg1, arg2) 类型的表达式函数 统一parser 成T_FUN_SYS 类型,函数名存在子结点里

  • 【resolver 模块】: 根据节点 T_FUN_SYS 类型 执行 process_fun_sys_node函数

  • 【resolver 模块】: 根据函数名字查找类型:ObExprOperatorFactory::get_type_by_name(func_name)

  • 【ob_expr_operator_factory.cpp】表达式名字 和类型 通过自定义实现类 提前注册REG_OP

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#define REG_OP(OpClass)                                                \
  do {                                                                 \
    OpClass op(alloc);                                                 \
    if (OB_UNLIKELY(i >= EXPR_OP_NUM)) {                               \
      LOG_ERROR("out of the max expr");                                \
    } else {                                                           \
      NAME_TYPES[i].name_ = op.get_name();                             \
      NAME_TYPES[i].type_ = op.get_type();                             \
      OP_ALLOC[op.get_type()] = ObExprOperatorFactory::alloc<OpClass>; \
      i++;                                                             \
    }                                                                  \
  } while (0)
  • 【ob_expr_time.cpp】自定义表达式类:在定义构造时候 初始化了 表达式的名字 和类型【写死了】
1
2
3
ObExprDayName::ObExprDayName(ObIAllocator& alloc)
    : ObExprTimeBase(alloc, DT_DAY_NAME, T_FUN_SYS_DAY_NAME, N_DAY_NAME){};
#define N_DAY_NAME "dayname"
  • [表达式内置函数] virtual cg_expr 注册自己实现函数到 eval_func_
  • 【表达式内置函数】提供函数注册是的内存分配,类型定义

calc_result_type1 返回值的类型 calc_result_type2 返回值的类型

看到这里可用了 下面个人测试 和阅读记录


2.3 详细描述

ob_raw_expr_resolver_impl.cpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#781
 case T_FUN_SYS: {
          if (OB_FAIL(process_fun_sys_node(node, expr))) {
            if (ret != OB_ERR_FUNCTION_UNKNOWN) {
              LOG_WARN("fail to process system function node", K(ret), K(node));
            } else if (OB_FAIL(process_dll_udf_node(node, expr))) {
              if (ret != OB_ERR_FUNCTION_UNKNOWN) {
                LOG_WARN("fail to process dll user function node", K(ret), K(node));
              } else {
                ParseNode* udf_node = NULL;
                ObString empty_db_name;
                ObString empty_pkg_name;
                bool record_udf_info = true;
                if (OB_FAIL(ObResolverUtils::transform_func_sys_to_udf(
                        &ctx_.expr_factory_.get_allocator(), node, empty_db_name, empty_pkg_name, udf_node))) {
                  LOG_WARN("transform func sys to udf node failed", K(ret));
                } else if (OB_ISNULL(expr)) {
                  ret = OB_ERR_FUNCTION_UNKNOWN;
                  LOG_WARN("function does not exist", K(node->children_[0]->str_value_));
                  LOG_USER_ERROR(
                      OB_ERR_FUNCTION_UNKNOWN, (int32_t)node->children_[0]->str_len_, node->children_[0]->str_value_);
                }
              }
            }
          }
          break;
        }

else if (OB_ISNULL(expr)) {
                  ret = OB_ERR_FUNCTION_UNKNOWN;
                  LOG_WARN("function does not exist", K(node->children_[0]->str_value_));
                  LOG_USER_ERROR(
                      OB_ERR_FUNCTION_UNKNOWN, (int32_t)node->children_[0]->str_len_, node->children_[0]->str_value_);
                }
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  REG_OP(ObExprDayOfWeek);

class ObExprDayOfWeek : public ObExprTimeBase {
public:
  ObExprDayOfWeek();
  explicit ObExprDayOfWeek(common::ObIAllocator& alloc);
  virtual ~ObExprDayOfWeek();
  static int calc_dayofweek(const ObExpr& expr, ObEvalCtx& ctx, ObDatum& expr_datum);

private:
  DISALLOW_COPY_AND_ASSIGN(ObExprDayOfWeek);
};

int ObExprDayOfWeek::calc_dayofweek(const ObExpr& expr, ObEvalCtx& ctx, ObDatum& expr_datum)
{
  int ret = OB_SUCCESS;
  if (ObExprTimeBase::calc(expr, ctx, expr_datum, DT_WDAY, true)) {
    LOG_WARN("calc day of week failed", K(ret));
  } else if (!expr_datum.is_null()) {
    expr_datum.set_int32(expr_datum.get_int32() % 7 + 1);
  }
  return ret;
}

src\sql\engine\expr\ob_expr_time.cpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
/root/src/oceanbase/deps/oblib/src/lib/timezone

deps\oblib\src\lib\timezone\ob_time_convert.h

int ObExprTimeBase::cg_expr

 case DT_MON_NAME:
        rt_expr.eval_func_ = ObExprMonthName::calc_month_name;
        break;
/root/src/oceanbase/src/sql/engine/expr

in ObExprTimeBase::calc_result1(ObObj& result, const ObObj& obj, ObExprCtx& expr_ctx) const


    static ObExpr::EvalFunc g_expr_eval_functions[] 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
int ObExprTimeBase::calc_result1(ObObj& result, const ObObj& obj, ObExprCtx& expr_ctx) const
{
  int ret = OB_SUCCESS;
  if (OB_UNLIKELY(obj.is_null())) {
    result.set_null();
  } else {
    ObTime ot;
    bool with_date = false;
    switch (dt_type_) {
      case DT_HOUR:
      case DT_MIN:
      case DT_SEC:
      case DT_USEC:
        with_date = false;
        break;
      case DT_YDAY:
      case DT_WDAY:
      case DT_MDAY:
      case DT_YEAR:
      case DT_MON:
        with_date = true;
        break;
      case DT_MON_NAME:
      case DT_DAY_NAME:
        with_date = true;
        break;
              
      default:
        LOG_WARN("ObExprTimeBase calc result1 switch default", K(dt_type_));
    }
    bool ignoreZero = (DT_MDAY == dt_type_ || DT_MON == dt_type_ || DT_MON_NAME == dt_type_);
    if (OB_FAIL(ob_expr_convert_to_dt_or_time(obj, expr_ctx, ot, with_date, ignoreZero))) {
      LOG_WARN("cast to ob time failed", K(ret), K(obj), K(expr_ctx.cast_mode_));
      if (CM_IS_WARN_ON_FAIL(expr_ctx.cast_mode_)) {
        LOG_WARN("cast to ob time failed", K(ret), K(expr_ctx.cast_mode_));
        LOG_USER_WARN(OB_ERR_CAST_VARCHAR_TO_TIME);
        ret = OB_SUCCESS;
        result.set_null();
      }
    } else {
      if (with_date && DT_MDAY != dt_type_ && ot.parts_[DT_DATE] + DAYS_FROM_ZERO_TO_BASE < 0) {
        result.set_null();
      } else if (DT_WDAY == dt_type_) {
        int32_t res = ot.parts_[DT_WDAY];
        res = res % 7 + 1;
        result.set_int32(res);
      } else if (DT_MON_NAME == dt_type_) {
        int32_t mon = ot.parts_[DT_MON];
        if (mon < 1 || mon > 12) {
          LOG_WARN("invalid month value", K(ret), K(mon));
          result.set_null();
        } else {
          const char* month_name = ObExprMonthName::get_month_name(ot.parts_[DT_MON]);
          result.set_string(common::ObVarcharType, month_name, strlen(month_name));
          result.set_collation_type(result_type_.get_collation_type());
          result.set_collation_level(result_type_.get_collation_level());
        }
      } else {
        result.set_int32(ot.parts_[dt_type_]);
      }
    }
  }
  return ret;
}

ObExprMonthName::ObExprMonthName(ObIAllocator& alloc)
    : ObExprTimeBase(alloc, DT_MON_NAME, T_FUN_SYS_MONTH_NAME, N_MONTH_NAME){};
#define N_MONTH_NAME "monthname"

int ObExprDayOfWeek::calc_dayofweek(const ObExpr& expr, ObEvalCtx& ctx, ObDatum& expr_datum)
{
  int ret = OB_SUCCESS;
  if (ObExprTimeBase::calc(expr, ctx, expr_datum, DT_WDAY, true)) {
    LOG_WARN("calc day of week failed", K(ret));
  } else if (!expr_datum.is_null()) {
    expr_datum.set_int32(expr_datum.get_int32() % 7 + 1);
  }
  return ret;
}

src\sql\parser\ob_item_type.h

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// system function for mysql only
T_FUN_SYS_MONTH_NAME = 708, //sql 命令 怎么知道那个函数执行
#define N_MONTH_NAME "monthname"


ObExprMonthName::ObExprMonthName(ObIAllocator& alloc)
    : ObExprTimeBase(alloc, DT_MON_NAME, T_FUN_SYS_MONTH_NAME, N_MONTH_NAME){};

ObExprIsIpv4::ObExprIsIpv4(ObIAllocator& alloc)
    : ObFuncExprOperator(alloc, T_FUN_SYS_IS_IPV4, N_IS_IPV4, 1, NOT_ROW_DIMENSION)
{}

2.3 测试过程

  • 根据日志看函数调用关系。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

 stmt_query (ob_sql.cpp:171) [112642][466][YB427F000001-0005E8344D6D28DD] [lt=3] [dc=0] fail to handle text query(stmt=SELECT DAYNAME("2017-06-15"), ret=-5055)

     
else if (OB_FAIL(handle_text_query(stmt, context, result))) {
    if (OB_EAGAIN != ret && OB_ERR_PROXY_REROUTE != ret) {
      LOG_WARN("fail to handle text query", K(stmt), K(ret));
    }
  }

int ObSql::handle_text_query(

    [root@h12-storage03 log]# tail -f observer.log |grep "not exist"
[2022-09-09 11:17:54.141943] INFO  [SHARE.SCHEMA] ob_schema_getter_guard.cpp:6335 [112642][466][YB427F000001-0005E8344D6D28DF] [lt=9] [dc=0] udf not exist(tenant_id=1, name=dayname)
[2022-09-09 11:17:54.141953] WARN  [SQL.RESV] do_recursive_resolve (ob_raw_expr_resolver_impl.cpp:798) [112642][466][YB427F000001-0005E8344D6D28DF] [lt=7] [dc=0] function does not exist(node->children_[0]->str_value_="DAYNAME")
[2022-09-09 11:17:54.141966] WARN  do_recursive_resolve (ob_raw_expr_resolver_impl.cpp:800) [112642][466][YB427F000001-0005E8344D6D28DF] [lt=11] [dc=0] FUNCTION DAYNAME does not exist
[2022-09-09 11:17:54.142091] INFO  [SERVER] obmp_base.cpp:1237 [112642][466][YB427F000001-0005E8344D6D28DF] [lt=4] [dc=0] send error package.(user_error_code=1305, err=-5055, sql_state="42000", message=FUNCTION DAYNAME does not exist
)


[5]+  Stopped                 tail -f observer.log | grep --color=auto "not exist"
[root@h12-storage03 log]# grep "YB427F000001-0005E8344D6D28DF" observer.log
[2022-09-09 11:17:54.141719] INFO  [SQL] ob_sql.cpp:163 [112642][466][YB427F000001-0005E8344D6D28DF] [lt=8] [dc=0] Begin to handle text statement(trunc_stmt=SELECT DAYNAME("2017-06-15"), sess_id=3221487631, execution_id=194262)
[2022-09-09 11:17:54.141943] INFO  [SHARE.SCHEMA] ob_schema_getter_guard.cpp:6335 [112642][466][YB427F000001-0005E8344D6D28DF] [lt=9] [dc=0] udf not exist(tenant_id=1, name=dayname)
[2022-09-09 11:17:54.141953] WARN  [SQL.RESV] do_recursive_resolve (ob_raw_expr_resolver_impl.cpp:798) [112642][466][YB427F000001-0005E8344D6D28DF] [lt=7] [dc=0] function does not exist(node->children_[0]->str_value_="DAYNAME")
[2022-09-09 11:17:54.141966] WARN  do_recursive_resolve (:800) [112642][466][YB427F000001-0005E8344D6D28DF] [lt=11] [dc=0] FUNCTION DAYNAME does not exist
[2022-09-09 11:17:54.141975] WARN  [SQL.RESV] resolve_sql_expr (ob_dml_resolver.cpp:208) [112642][466][YB427F000001-0005E8344D6D28DF] [lt=2] [dc=0] fail to exec expr_resolver.resolve( &node, expr, *output_columns, sys_vars, sub_query_info, aggr_exprs, win_exprs, op_exprs, user_var_exprs)(ret=-5055, &node=0x7f07f2e6aa18, expr=NULL, *output_columns=[], sys_vars=[], sub_query_info=[], aggr_exprs=[], win_exprs=[], op_exprs=[], user_var_exprs=[])
[2022-09-09 11:17:54.141985] WARN  [SQL.RESV] resolve_field_list :1399) [112642][466][YB427F000001-0005E8344D6D28DF] [lt=5] [dc=0] resolve sql expr failed(ret=-5055)
[2022-09-09 11:17:54.141989] WARN  [SQL.RESV] resolve_normal_query (ob_select_resolver.cpp:801) [112642][466][YB427F000001-0005E8344D6D28DF] [lt=2] [dc=0] fail to exec resolve_field_list(*(parse_tree.children_[PARSE_SELECT_SELECT]))(ret=-5055)
[2022-09-09 11:17:54.141992] WARN  [SQL.RESV] resolve (ob_select_resolver.cpp:934) [112642][466][YB427F000001-0005E8344D6D28DF] [lt=2] [dc=0] resolve normal query failed(ret=-5055)
[2022-09-09 11:17:54.141996] WARN  [SQL.RESV] select_stmt_resolver_func (ob_resolver.cpp:142) [112642][466][YB427F000001-0005E8344D6D28DF] [lt=2] [dc=0] execute stmt_resolver failed(ret=-5055, parse_tree.type_=3035)
[2022-09-09 11:17:54.142005] WARN  [SQL] generate_stmt (ob_sql.cpp:1443) [112642][466][YB427F000001-0005E8344D6D28DF] [lt=2] [dc=0] failed to resolve(ret=-5055)
[2022-09-09 11:17:54.142010] WARN  [SQL] generate_physical_plan (ob_sql.cpp:1531) [112642][466][YB427F000001-0005E8344D6D28DF] [lt=3] [dc=0] Failed to generate stmt(ret=-5055, result.get_exec_context().need_disconnect()=false)
[2022-09-09 11:17:54.142014] WARN  [SQL] handle_physical_plan (ob_sql.cpp:3231) [112642][466][YB427F000001-0005E8344D6D28DF] [lt=2] [dc=0] Failed to generate plan(ret=-5055, result.get_exec_context().need_disconnect()=false)
[2022-09-09 11:17:54.142018] WARN  [SQL] handle_text_query (ob_sql.cpp:1212) [112642][466][YB427F000001-0005E8344D6D28DF] [lt=2] [dc=0] fail to handle physical plan(ret=-5055)
[2022-09-09 11:17:54.142023] WARN  [SQL] stmt_query (ob_sql.cpp:171) [112642][466][YB427F000001-0005E8344D6D28DF] [lt=2] [dc=0] fail to handle text query(stmt=SELECT DAYNAME("2017-06-15"), ret=-5055)
[2022-09-09 11:17:54.142035] WARN  [SERVER] test_and_save_retry_state (ob_query_retry_ctrl.cpp:446) [112642][466][YB427F000001-0005E8344D6D28DF] [lt=3] [dc=0] do not need retry(client_ret=-5055, err=-5055, expected_stmt=true, THIS_WORKER.get_timeout_ts()=1662693484141630, retry_type_=0, result.get_stmt_type()=1, result.get_exec_context().need_change_timeout_ret()=true, session->get_retry_info().get_last_query_retry_err()=0)
[2022-09-09 11:17:54.142042] INFO  [SERVER] ob_query_retry_ctrl.cpp:460 [112642][466][YB427F000001-0005E8344D6D28DF] [lt=4] [dc=0] check if need retry(client_ret=-5055, err=-5055, retry_type_=0, retry_times=1, multi_stmt_item={is_part_of_multi_stmt:true, seq_num:0, sql:"SELECT DAYNAME("2017-06-15")"})
[2022-09-09 11:17:54.142049] WARN  [SERVER] do_process (obmp_query.cpp:638) [112642][466][YB427F000001-0005E8344D6D28DF] [lt=4] [dc=0] run stmt_query failed, check if need retry(ret=-5055, cli_ret=-5055, retry_ctrl_.need_retry()=0, sql=SELECT DAYNAME("2017-06-15"))
[2022-09-09 11:17:54.142063] WARN  [SERVER] do_process (obmp_query.cpp:745) [112642][466][YB427F000001-0005E8344D6D28DF] [lt=4] [dc=0] query failed(ret=-5055, retry_ctrl_.need_retry()=0)
[2022-09-09 11:17:54.142083] INFO  [SERVER] obmp_base.cpp:1163 [112642][466][YB427F000001-0005E8344D6D28DF] [lt=4] [dc=0] sending error packet(err=-5055, bt="0xb553645 0xa899d40 0xa92d3cd 0xa8c70ce 0xa8c151b 0xb6d881d 0xa740c40 0xa71d3f9 0xa73e9d6 0xa71b2ff 0xa71b7cc 0x1e7613c 0x1e75fcd 0x1e7a00e 0xb4fbd75 0xb4fa515 0xb20b1cf", extra_err_info=0x7f07f2e578c8)
[2022-09-09 11:17:54.142091] INFO  [SERVER] obmp_base.cpp:1237 [112642][466][YB427F000001-0005E8344D6D28DF] [lt=4] [dc=0] send error package.(user_error_code=1305, err=-5055, sql_state="42000", message=FUNCTION DAYNAME does not exist)
[2022-09-09 11:17:54.142161] WARN  [SERVER] process (obmp_query.cpp:291) [112642][466][YB427F000001-0005E8344D6D28DF] [lt=3] [dc=0] fail execute sql(sql_id="", sql=SELECT DAYNAME("2017-06-15"), sessid=3221487631, ret=-5055, ret="OB_ERR_FUNCTION_UNKNOWN", need_disconnect=false)
[root@h12-storage03 log]#

SELECT DAYNAME("2022-09-20");
SELECT DAYOFWEEK('2022-09-20');
SELECT MONTHNAME('2022-09-20');



cp /root/src/oceanbase/build_debug/src/observer/observer /root/src/observer/bin/observer
obd cluster stop test

第二次测试

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[root@h12-storage03 log]# tail -f observer.log |grep DAYNAME
[2022-09-20 21:04:42.773166] INFO  [SQL] ob_sql.cpp:163 [437909][466][YB427F000001-0005E91B467985A3] [lt=9] [dc=0] Begin to handle text statement(trunc_stmt=SELECT DAYNAME("2022-09-20"), sess_id=3221487618, execution_id=62341)
[2022-09-20 21:04:42.773450] WARN  [SQL.RESV] do_recursive_resolve (ob_raw_expr_resolver_impl.cpp:798) [437909][466][YB427F000001-0005E91B467985A3] [lt=7] [dc=0] function does not exist(node->children_[0]->str_value_="DAYNAME")
[2022-09-20 21:04:42.773456] WARN  do_recursive_resolve (ob_raw_expr_resolver_impl.cpp:800) [437909][466][YB427F000001-0005E91B467985A3] [lt=4] [dc=0] FUNCTION DAYNAME does not exist
[2022-09-20 21:04:42.773517] WARN  [SQL] stmt_query (ob_sql.cpp:171) [437909][466][YB427F000001-0005E91B467985A3] [lt=2] [dc=0] fail to handle text query(stmt=SELECT DAYNAME("2022-09-20"), ret=-5055)
[2022-09-20 21:04:42.773537] INFO  [SERVER] ob_query_retry_ctrl.cpp:460 [437909][466][YB427F000001-0005E91B467985A3] [lt=5] [dc=0] check if need retry(client_ret=-5055, err=-5055, retry_type_=0, retry_times=1, multi_stmt_item={is_part_of_multi_stmt:true, seq_num:0, sql:"SELECT DAYNAME("2022-09-20")"})
[2022-09-20 21:04:42.773542] WARN  [SERVER] do_process (obmp_query.cpp:638) [437909][466][YB427F000001-0005E91B467985A3] [lt=4] [dc=0] run stmt_query failed, check if need retry(ret=-5055, cli_ret=-5055, retry_ctrl_.need_retry()=0, sql=SELECT DAYNAME("2022-09-20"))
[2022-09-20 21:04:42.773995] INFO  [SERVER] obmp_base.cpp:1237 [437909][466][YB427F000001-0005E91B467985A3] [lt=4] [dc=0] send error package.(user_error_code=1305, err=-5055, sql_state="42000", message=FUNCTION DAYNAME does not exist)
[2022-09-20 21:04:42.774084] WARN  [SERVER] process (obmp_query.cpp:291) [437909][466][YB427F000001-0005E91B467985A3] [lt=7] [dc=0] fail execute sql(sql_id="", sql=SELECT DAYNAME("2022-09-20"), sessid=3221487618, ret=-5055, ret="OB_ERR_FUNCTION_UNKNOWN", need_disconnect=false)
[2022-09-20 21:04:45.975760] INFO  [SQL] ob_sql.cpp:163 [437909][466][YB427F000001-0005E91B467985A4] [lt=8] [dc=0] Begin to handle text statement(trunc_stmt=SELECT DAYNAME("2022-09-20"), sess_id=3221487618, execution_id=62397)
[2022-09-20 21:04:45.976064] WARN  [SQL.RESV] do_recursive_resolve (ob_raw_expr_resolver_impl.cpp:798) [437909][466][YB427F000001-0005E91B467985A4] [lt=8] [dc=0] function does not exist(node->children_[0]->str_value_="DAYNAME")
[2022-09-20 21:04:45.976072] WARN  do_recursive_resolve (ob_raw_expr_resolver_impl.cpp:800) [437909][466][YB427F000001-0005E91B467985A4] [lt=5] [dc=0] FUNCTION DAYNAME does not exist
[2022-09-20 21:04:45.976166] WARN  [SQL] stmt_query (ob_sql.cpp:171) [437909][466][YB427F000001-0005E91B467985A4] [lt=4] [dc=0] fail to handle text query(stmt=SELECT DAYNAME("2022-09-20"), ret=-5055)
[2022-09-20 21:04:45.976194] INFO  [SERVER] ob_query_retry_ctrl.cpp:460 [437909][466][YB427F000001-0005E91B467985A4] [lt=6] [dc=0] check if need retry(client_ret=-5055, err=-5055, retry_type_=0, retry_times=1, multi_stmt_item={is_part_of_multi_stmt:true, seq_num:0, sql:"SELECT DAYNAME("2022-09-20")"})
[2022-09-20 21:04:45.976203] WARN  [SERVER] do_process (obmp_query.cpp:638) [437909][466][YB427F000001-0005E91B467985A4] [lt=6] [dc=0] run stmt_query failed, check if need retry(ret=-5055, cli_ret=-5055, retry_ctrl_.need_retry()=0, sql=SELECT DAYNAME("2022-09-20"))
[2022-09-20 21:04:45.976258] INFO  [SERVER] obmp_base.cpp:1237 [437909][466][YB427F000001-0005E91B467985A4] [lt=4] [dc=0] send error package.(user_error_code=1305, err=-5055, sql_state="42000", message=FUNCTION DAYNAME does not exist)
[2022-09-20 21:04:45.976355] WARN  [SERVER] process (obmp_query.cpp:291) [4

cp /root/src/oceanbase/build_debug/src/observer/observer /root/src/observer/bin/observer

                                                                         
obclient [oceanbase]> SELECT DAYOFWEEK('2022-09-20');
+-------------------------+
| DAYOFWEEK('2022-09-20') |
+-------------------------+
|                       3 |
+-------------------------+
Returns the weekday index for date (1 = Sunday, 2 = Monday, , 7 = Saturday). These index values correspond to the ODBC standard. Returns NULL if date is NUL
SELECT MONTHNAME('2022-09-20');
SELECT DAYNAME("2022-09-20");
select dayname("1962-03-01");

cp /root/oceanbase/build_debug/src/observer/observer /root/observer/bin/observer
                                                                          

三、 Conclusion