From 0a9f1e0c4f618bf9b954cebaac1a0bdd35fc7c99 Mon Sep 17 00:00:00 2001 From: AntiTopQuark Date: Thu, 13 Apr 2023 05:59:54 +0000 Subject: [PATCH] bugfix : level param in weight_string expr clause has core dump in fast parser --- src/objit/include/objit/common/ob_item_type.h | 1 + src/sql/ob_sql_utils.h | 4 ---- src/sql/parser/sql_parser_mysql_mode.y | 8 +++---- .../plan_cache/ob_sql_parameterization.cpp | 21 +++++++------------ .../expr/ob_raw_expr_resolver_impl.cpp | 10 +++++++++ 5 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/objit/include/objit/common/ob_item_type.h b/src/objit/include/objit/common/ob_item_type.h index ab5253177..321a35593 100755 --- a/src/objit/include/objit/common/ob_item_type.h +++ b/src/objit/include/objit/common/ob_item_type.h @@ -792,6 +792,7 @@ typedef enum ObItemType T_FUN_SYS_JSON_EXISTS = 1686, T_FUN_SYS_TREAT = 1687, T_NULLX_CLAUSE = 1688, // null clause on json expr + T_WEIGHT_STRING_LEVEL_PARAM = 1689, // `level 1-2` and `level 1,2,3` clause on json expr ///< @note add new oracle only function type before this line diff --git a/src/sql/ob_sql_utils.h b/src/sql/ob_sql_utils.h index debf77533..24453addd 100644 --- a/src/sql/ob_sql_utils.h +++ b/src/sql/ob_sql_utils.h @@ -685,14 +685,12 @@ struct ObSqlTraits bool is_modify_tenant_stmt_; bool is_cause_implicit_commit_; bool is_commit_stmt_; - bool has_weight_string_func_stmt_; // sql中是否包含weight_string函数 ObItemType stmt_type_; ObSqlTraits() : is_readonly_stmt_(false), is_modify_tenant_stmt_(false), is_cause_implicit_commit_(false), is_commit_stmt_(false), - has_weight_string_func_stmt_(false), stmt_type_(T_INVALID) { sql_id_[common::OB_MAX_SQL_ID_LENGTH] = '\0'; @@ -704,14 +702,12 @@ struct ObSqlTraits is_modify_tenant_stmt_ = false; is_cause_implicit_commit_ = false; is_commit_stmt_ = false; - has_weight_string_func_stmt_ = false; stmt_type_ = T_INVALID; } TO_STRING_KV(K(is_readonly_stmt_), K(is_modify_tenant_stmt_), K(is_cause_implicit_commit_), K(is_commit_stmt_), - K(has_weight_string_func_stmt_), K(stmt_type_)); }; diff --git a/src/sql/parser/sql_parser_mysql_mode.y b/src/sql/parser/sql_parser_mysql_mode.y index 860bba457..7724a1bbc 100755 --- a/src/sql/parser/sql_parser_mysql_mode.y +++ b/src/sql/parser/sql_parser_mysql_mode.y @@ -3116,9 +3116,9 @@ ws_level_list_item } | ws_level_list ',' ws_level_list_item { - malloc_terminal_node($$, result->malloc_pool_, T_INT); + malloc_terminal_node($$, result->malloc_pool_, T_WEIGHT_STRING_LEVEL_PARAM); $$->value_ = $3->value_ | $1->value_; - $$->param_num_ = 1; + $$->param_num_ = $1->param_num_ + $3->param_num_; } ; @@ -3134,7 +3134,7 @@ ws_level_number ws_level_flags ws_level_range: ws_level_number '-' ws_level_number { - malloc_terminal_node($$, result->malloc_pool_, T_INT); + malloc_terminal_node($$, result->malloc_pool_, T_WEIGHT_STRING_LEVEL_PARAM); uint32_t res = 0; uint32_t start = $1->value_ ; uint32_t end = $3->value_ ; @@ -3145,7 +3145,7 @@ ws_level_number '-' ws_level_number res |= (1 << start); } $$->value_ = res; - $$->param_num_ = 1; + $$->param_num_ = 2; } ; diff --git a/src/sql/plan_cache/ob_sql_parameterization.cpp b/src/sql/plan_cache/ob_sql_parameterization.cpp index 6fabf5f21..e8db0346e 100644 --- a/src/sql/plan_cache/ob_sql_parameterization.cpp +++ b/src/sql/plan_cache/ob_sql_parameterization.cpp @@ -255,7 +255,8 @@ int ObSqlParameterization::is_fast_parse_const(TransformTreeCtx &ctx) || T_CAST_ARGUMENT == ctx.tree_->type_ || T_NULLX_CLAUSE == ctx.tree_->type_ || (T_SFU_INT == ctx.tree_->type_ && -1 != ctx.tree_->value_) - || T_SFU_DECIMAL == ctx.tree_->type_); + || T_SFU_DECIMAL == ctx.tree_->type_ + || T_WEIGHT_STRING_LEVEL_PARAM == ctx.tree_->type_); } } else { ctx.is_fast_parse_const_ = false; @@ -452,7 +453,7 @@ bool ObSqlParameterization::is_ignore_scale_check(TransformTreeCtx &ctx, const P * select weight_string("AAA" as char(1) level 1-2 ); * select weight_string("AAA" as char(1) level 1,2,3,4,5,6,7,8,9,10,11 ); * select weight_string("AAA" as char(1) level 1 desc,2 asc ,3 desc ,4 reverse,5,6,7,8,9 reverse,10,11 ); -* 解法:由于这个函数是一个debug的函数,是用来测试collation是否正确的。不是特别需要使用plan_cache来提高性能。为了解决在check_and_generate_param_info()内的"const number of fast parse and normal parse is different"的ERROR。在sql_info.sql_traits_中新增了bool变量,命名为has_weight_string_func_stmt_,表示sql中是否包含wegiht_string函数。如果该变量为True,则跳过报错的逻辑。 +* 解法:创建一个新的item_type(T_WEIGHT_STRING_LEVEL_PARAM) ,根据不同的语法来设置不同的param_num_,这样normal_parser就可以和faster_parser相等了,等到具体处理T_WEIGHT_STRING_LEVEL_PARAM的时候,把它转换为T_INT进行后续的处理。 */ int ObSqlParameterization::transform_tree(TransformTreeCtx &ctx, const ObSQLSessionInfo &session_info) @@ -858,15 +859,9 @@ int ObSqlParameterization::check_and_generate_param_info(const ObIArraytype_ //如果是cast类型,则需要添加N个cast节点对应的常数, 因为正常parse不识别为常量, 但fast parse时会识别为常量 || T_COLLATION == node->type_ - || T_NULLX_CLAUSE == node->type_) { // deal null clause on json expr + || T_NULLX_CLAUSE == node->type_ // deal null clause on json expr + || T_WEIGHT_STRING_LEVEL_PARAM == node->type_) { for (int i = 0; OB_SUCC(ret) && i < node->param_num_; ++i) { if (OB_FAIL(sql_info.not_param_index_.add_member(sql_info.total_++))) { SQL_PC_LOG(WARN, "failed to add member", K(sql_info.total_)); @@ -1554,7 +1550,6 @@ int ObSqlParameterization::mark_tree(ParseNode *tree ,SqlInfo &sql_info) && (5 == node[1]->num_child_)) { const int64_t ARGS_NUMBER_FIVE = 5; bool mark_arr[ARGS_NUMBER_FIVE] = {0, 1, 1, 1, 1}; //0表示参数化, 1 表示不参数化 - sql_info.sql_traits_.has_weight_string_func_stmt_ = true; if (OB_FAIL(mark_args(node[1], mark_arr, ARGS_NUMBER_FIVE, sql_info))) { SQL_PC_LOG(WARN, "fail to mark weight_string arg", K(ret)); } diff --git a/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp b/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp index 857d16546..3b9f5cede 100644 --- a/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp @@ -940,6 +940,15 @@ int ObRawExprResolverImpl::do_recursive_resolve(const ParseNode *node, ObRawExpr } break; } + case T_WEIGHT_STRING_LEVEL_PARAM: { + modification_type_to_int(const_cast(*node)); + // deal node + if (OB_FAIL(SMART_CALL(recursive_resolve(node, expr)))) { + LOG_WARN("fail to process node with children only", K(ret), + K(node->type_), K(node)); + } + break; + } case T_FUN_SYS_REGEXP_LIKE: case T_FUN_SYS: { if (OB_FAIL(process_fun_sys_node(node, expr))) { @@ -5360,6 +5369,7 @@ int ObRawExprResolverImpl::pre_check_json_path_valid(const ParseNode *node) } // json expr change T_NULLX_CLAUSE to T_INT +// and weight_string expr change T_WEIGHT_STRING_LEVEL_PARAM to T_INT void ObRawExprResolverImpl::modification_type_to_int(ParseNode &node) { node.type_ = T_INT;