diff --git a/src/rootserver/ddl_task/ob_drop_fts_index_task.cpp b/src/rootserver/ddl_task/ob_drop_fts_index_task.cpp index 1997dee84d..f003f77361 100644 --- a/src/rootserver/ddl_task/ob_drop_fts_index_task.cpp +++ b/src/rootserver/ddl_task/ob_drop_fts_index_task.cpp @@ -280,7 +280,30 @@ int ObDropFTSIndexTask::check_switch_succ() && OB_FAIL(schema_guard.check_table_exist(tenant_id_, rowkey_doc_.table_id_, is_rowkey_doc_exist))) { LOG_WARN("fail to check table exist", K(ret), K(tenant_id_), K(rowkey_doc_)); } else if (!is_domain_index_exist && !is_doc_word_exist && !is_rowkey_doc_exist && !is_doc_rowkey_exist) { - task_status_ = ObDDLTaskStatus::SUCCESS; + uint64_t doc_id_col_id = OB_INVALID_ID; + uint64_t ft_col_id = OB_INVALID_ID; + const ObTableSchema *data_table_schema = nullptr; + bool has_fts_index = false; + bool has_multivalue_index = false; + + int tmp_ret = schema_guard.get_table_schema(tenant_id_, object_id_, data_table_schema); + if (tmp_ret != OB_SUCCESS) { + } else if (OB_ISNULL(data_table_schema)) { + } else if ((tmp_ret = data_table_schema->check_has_fts_index(schema_guard, has_fts_index))!= OB_SUCCESS) { + } else if ((tmp_ret = data_table_schema->check_has_multivalue_index(schema_guard, has_multivalue_index))!= OB_SUCCESS) { + } else if (!has_fts_index && !has_multivalue_index + && (tmp_ret = data_table_schema->get_fulltext_column_ids(doc_id_col_id, ft_col_id)) != OB_SUCCESS) { + } + + // 主表存在,并且fts,multivalue索引不存在了,doc-id列从主表中移除 + // 否则可能出现小概率的dml的时候,schema没有刷新,导致cg阶段多了doc-id列 + if (tmp_ret == OB_SUCCESS + && OB_ISNULL(data_table_schema) + && doc_id_col_id != OB_INVALID_ID) { + // do nothing + } else { + task_status_ = ObDDLTaskStatus::SUCCESS; + } } return ret; } @@ -529,7 +552,11 @@ int ObDropFTSIndexTask::create_drop_doc_rowkey_task() int ObDropFTSIndexTask::succ() { - return cleanup(); + int ret = OB_SUCCESS; + if (OB_FAIL(cleanup())) { + LOG_WARN("cleanup task failed", K(ret)); + } + return ret; } int ObDropFTSIndexTask::fail() diff --git a/src/sql/engine/expr/ob_expr_json_func_helper.h b/src/sql/engine/expr/ob_expr_json_func_helper.h index 4164f40973..54db07caf0 100644 --- a/src/sql/engine/expr/ob_expr_json_func_helper.h +++ b/src/sql/engine/expr/ob_expr_json_func_helper.h @@ -52,7 +52,7 @@ public: error_type_(0), is_empty_default_const_(false), is_error_default_const_(false), - is_alias_(false), + is_asis_(false), is_multivalue_(false), empty_val_(), error_val_(), @@ -76,7 +76,7 @@ public: int8_t error_type_; bool is_empty_default_const_; bool is_error_default_const_; - bool is_alias_; + bool is_asis_; bool is_multivalue_; ObDatum *empty_val_; ObDatum *error_val_; diff --git a/src/sql/engine/expr/ob_expr_json_query.cpp b/src/sql/engine/expr/ob_expr_json_query.cpp index cff57ae3dd..a3edf57a79 100644 --- a/src/sql/engine/expr/ob_expr_json_query.cpp +++ b/src/sql/engine/expr/ob_expr_json_query.cpp @@ -240,7 +240,6 @@ int ObExprJsonQuery::eval_json_query(const ObExpr &expr, ObEvalCtx &ctx, ObDatum is_cover_by_error = false; LOG_WARN("fail to init param ctx", K(ret)); } else if (OB_ISNULL(param_ctx->json_param_.json_path_) - && !param_ctx->json_param_.is_alias_ && OB_FAIL(ObJsonUtil::get_json_path(expr.args_[JSN_QUE_PATH], ctx, // parse json path is_null_result, param_ctx, temp_allocator, is_cover_by_error))) { // ctx_cache->path_cache_ @@ -250,14 +249,12 @@ int ObExprJsonQuery::eval_json_query(const ObExpr &expr, ObEvalCtx &ctx, ObDatum is_cover_by_error))) { // get clause param value, set into param_ctx LOG_WARN("fail to parse clause value", K(ret)); - } else if (!param_ctx->json_param_.is_multivalue_ && param_ctx->json_param_.is_alias_) { - is_null_result = true; } else if (OB_FAIL(ObJsonUtil::get_json_doc(expr.args_[JSN_QUE_DOC], ctx, temp_allocator, j_base, is_null_result, is_cover_by_error, true))) { // parse json doc LOG_WARN("get_json_doc failed", K(ret)); } else if (param_ctx->json_param_.json_path_ == nullptr) { // do seek - if (param_ctx->json_param_.is_alias_ && param_ctx->json_param_.is_multivalue_) { + if (param_ctx->json_param_.is_asis_) { if (OB_FAIL(hits.push_node(j_base))) { LOG_WARN("fail to store j-doc", K(ret)); } @@ -278,7 +275,7 @@ int ObExprJsonQuery::eval_json_query(const ObExpr &expr, ObEvalCtx &ctx, ObDatum ObCollationType dst_coll_type = expr.datum_meta_.cs_type_; ObJsonCastParam cast_param(param_ctx->json_param_.dst_type_, in_coll_type, dst_coll_type, 0); bool is_multivalue = param_ctx->json_param_.is_multivalue_; - bool is_alias = param_ctx->json_param_.is_alias_; + bool is_asis = param_ctx->json_param_.is_asis_; // fill output if (OB_FAIL(ret)) { @@ -289,10 +286,9 @@ int ObExprJsonQuery::eval_json_query(const ObExpr &expr, ObEvalCtx &ctx, ObDatum } LOG_WARN("json_query failed", K(ret)); } else if (is_null_result) { - // ToDo: need check is_multivalue? res.set_null(); - if (is_multivalue && - OB_FAIL(set_multivalue_result(ctx, temp_allocator, nullptr, expr, + if (is_asis && + OB_FAIL(set_multivalue_result(is_multivalue, ctx, temp_allocator, nullptr, expr, param_ctx->json_param_.error_type_, in_coll_type, dst_coll_type, param_ctx->json_param_.error_val_, @@ -329,8 +325,8 @@ int ObExprJsonQuery::eval_json_query(const ObExpr &expr, ObEvalCtx &ctx, ObDatum } if (try_set_error_val(&temp_allocator, ctx, ¶m_ctx->json_param_, expr, res, ret)) { - } else if (is_multivalue) { - if (OB_FAIL(set_multivalue_result(ctx, temp_allocator, jb_res, expr, + } else if (is_asis) { + if (OB_FAIL(set_multivalue_result(is_multivalue, ctx, temp_allocator, jb_res, expr, param_ctx->json_param_.error_type_, in_coll_type, dst_coll_type, param_ctx->json_param_.error_val_, @@ -344,46 +340,34 @@ int ObExprJsonQuery::eval_json_query(const ObExpr &expr, ObEvalCtx &ctx, ObDatum } else if (is_json_arr) { ObJsonArray j_arr_var(&temp_allocator); jb_empty = &j_arr_var; - if (is_multivalue || is_alias) { - if (!is_multivalue) { - res.set_null(); - } else { - ret = set_multivalue_result(ctx, temp_allocator, jb_empty, expr, + if (is_multivalue || is_asis) { + ret = set_multivalue_result(is_multivalue, ctx, temp_allocator, jb_empty, expr, param_ctx->json_param_.error_type_, in_coll_type, dst_coll_type, param_ctx->json_param_.error_val_, param_ctx->json_param_.accuracy_, cast_param, res); - } } else { ret = set_result(¶m_ctx->json_param_, jb_empty, &temp_allocator, ctx, expr, res); } } else if (is_json_obj) { ObJsonObject j_obj_var(&temp_allocator); jb_empty = &j_obj_var; - if (is_multivalue || is_alias) { - if (!is_multivalue) { - res.set_null(); - } else { - ret = set_multivalue_result(ctx, temp_allocator, jb_empty, expr, - param_ctx->json_param_.error_type_, - in_coll_type, dst_coll_type, - param_ctx->json_param_.error_val_, - param_ctx->json_param_.accuracy_, cast_param, res); - } + if (is_multivalue || is_asis) { + ret = set_multivalue_result(is_multivalue, ctx, temp_allocator, jb_empty, expr, + param_ctx->json_param_.error_type_, + in_coll_type, dst_coll_type, + param_ctx->json_param_.error_val_, + param_ctx->json_param_.accuracy_, cast_param, res); } else { ret = set_result(¶m_ctx->json_param_, jb_empty, &temp_allocator, ctx, expr, res); } } else { - if (is_multivalue || is_alias) { - if (!is_multivalue) { - res.set_null(); - } else { - ret = set_multivalue_result(ctx, temp_allocator, hits[0], expr, + if (is_multivalue || is_asis) { + ret = set_multivalue_result(is_multivalue, ctx, temp_allocator, hits[0], expr, param_ctx->json_param_.error_type_, in_coll_type, dst_coll_type, param_ctx->json_param_.error_val_, param_ctx->json_param_.accuracy_, cast_param, res); - } } else { ret = set_result(¶m_ctx->json_param_, hits[0], &temp_allocator, ctx, expr, res); } @@ -426,7 +410,8 @@ int ObExprJsonQuery::check_enable_cast_index_array(ObIJsonBase* json_base, bool return ret; } -int ObExprJsonQuery::set_multivalue_result(ObEvalCtx& ctx, +int ObExprJsonQuery::set_multivalue_result(bool is_result_array, + ObEvalCtx& ctx, ObIAllocator& allocator, ObIJsonBase* origin_result, const ObExpr &expr, @@ -452,6 +437,8 @@ int ObExprJsonQuery::set_multivalue_result(ObEvalCtx& ctx, ObAccuracy accuracy = origin_accuracy; ObIJsonBase* json_base = nullptr; + ObObj tmp_obj; + ObObj* object_ptr = &tmp_obj; if (OB_FAIL(expr.args_[2]->eval(ctx, opt_type))) { LOG_WARN("eval dst type datum failed", K(ret)); @@ -499,14 +486,15 @@ int ObExprJsonQuery::set_multivalue_result(ObEvalCtx& ctx, ObJsonBin tmp; ObIJsonBase* iter = &tmp; ObObj *tmp_array_obj = new (obj_array + i) ObObj(); - ObObj *tmp_obj = tmp_array_obj; + ObObj *temp_obj = tmp_array_obj; + object_ptr = temp_obj; if (OB_FAIL(json_base->get_array_element(i, iter))) { LOG_WARN("get json array element failed", K(ret)); } else if (OB_FAIL(check_enable_cast_index_array(iter, true, dest_type))) { LOG_WARN("failed to check index array size", K(ret)); } else if (OB_FAIL(ObJsonUtil::cast_json_scalar_to_sql_obj(&allocator, ctx, iter, dst_collation, - accuracy, dest_type, scale, *tmp_obj))) { + accuracy, dest_type, scale, *temp_obj))) { LOG_WARN("failed to cast to res", K(ret), K(dest_type)); ret = OB_ERR_JSON_VALUE_CAST_FUNCTION_INDEX; LOG_USER_ERROR(OB_ERR_JSON_VALUE_CAST_FUNCTION_INDEX); @@ -514,7 +502,7 @@ int ObExprJsonQuery::set_multivalue_result(ObEvalCtx& ctx, } // 2. do sort - if (OB_SUCC(ret) && OB_NOT_NULL(obj_array)) { + if (OB_SUCC(ret) && is_result_array && OB_NOT_NULL(obj_array)) { lib::ObMallocHookAttrGuard malloc_guard(lib::ObMemAttr(ObXMLExprHelper::get_tenant_id(ctx.exec_ctx_.get_my_session()), "JSONMultivalue")); ObJsonObjectCompare cmp; lib::ob_sort(obj_array, obj_array + element_count, cmp); @@ -522,51 +510,50 @@ int ObExprJsonQuery::set_multivalue_result(ObEvalCtx& ctx, uint32_t real_store_count = 0; ObObj *last_obj = nullptr; - for (int i = 0; OB_SUCC(ret) && i < element_count; ++i) { - ObObj *tmp_obj = obj_array + i; + for (int i = 0; OB_SUCC(ret) && is_result_array && i < element_count; ++i) { + ObObj *temp_obj = obj_array + i; int64_t pos = str_buff.length(); if (ob_is_numeric_type(dest_type) || ob_is_temporal_type(dest_type)) { - tmp_obj->set_collation_level(CS_LEVEL_NUMERIC); + temp_obj->set_collation_level(CS_LEVEL_NUMERIC); } else { - tmp_obj->set_collation_level(CS_LEVEL_IMPLICIT); + temp_obj->set_collation_level(CS_LEVEL_IMPLICIT); } // Remove duplicates int obj_cmp_ret = 0; if (OB_ISNULL(last_obj)) { ++real_store_count; - last_obj = tmp_obj; + last_obj = temp_obj; } else { - bool is_case_comp = last_obj->is_string_type() && tmp_obj->is_string_type(); - if (is_case_comp && OB_FAIL(last_obj->compare(*tmp_obj, CS_TYPE_UTF8MB4_GENERAL_CI, obj_cmp_ret))) { - LOG_WARN("failed compare obobj data", K(ret), K(*last_obj), K(*tmp_obj)); - } else if (!is_case_comp && OB_FAIL(last_obj->compare(*tmp_obj, obj_cmp_ret))) { - LOG_WARN("failed compare obobj data", K(ret), K(*last_obj), K(*tmp_obj)); + bool is_case_comp = last_obj->is_string_type() && temp_obj->is_string_type(); + if (is_case_comp && OB_FAIL(last_obj->compare(*temp_obj, CS_TYPE_UTF8MB4_GENERAL_CI, obj_cmp_ret))) { + LOG_WARN("failed compare obobj data", K(ret), K(*last_obj), K(*temp_obj)); + } else if (!is_case_comp && OB_FAIL(last_obj->compare(*temp_obj, obj_cmp_ret))) { + LOG_WARN("failed compare obobj data", K(ret), K(*last_obj), K(*temp_obj)); } else if (obj_cmp_ret == 0) { // ObCmpRes::CR_EQ continue; } else { - last_obj = tmp_obj; + last_obj = temp_obj; ++real_store_count; } } if (OB_FAIL(ret)) { - } else if (FALSE_IT(reserve_len = tmp_obj->get_serialize_size())) { + } else if (FALSE_IT(reserve_len = temp_obj->get_serialize_size())) { } else if (OB_FAIL(str_buff.reserve(reserve_len + 128))) { LOG_WARN("failed to reserve size", K(ret), K(reserve_len)); - } else if (OB_FAIL(tmp_obj->serialize(str_buff.ptr(), str_buff.capacity(), pos))) { + } else if (OB_FAIL(temp_obj->serialize(str_buff.ptr(), str_buff.capacity(), pos))) { LOG_WARN("failed to serialize datum", K(ret), K(reserve_len)); } else { str_buff.set_length(pos); } } - if (OB_SUCC(ret)) { + if (OB_SUCC(ret) && is_result_array) { // update real element count *reinterpret_cast(str_buff.ptr()) = real_store_count; } } else if (element_count > 0) { - ObObj tmp_obj; int64_t pos = str_buff.length(); if (ob_is_numeric_type(dest_type) || ob_is_temporal_type(dest_type)) { @@ -593,30 +580,41 @@ int ObExprJsonQuery::set_multivalue_result(ObEvalCtx& ctx, } else { // empty result, set a minimal - ObObj tmp_obj; - tmp_obj.set_type(dest_type); - tmp_obj.set_collation_type(dst_collation); - tmp_obj.set_scale(scale); + ObObj temp_obj; + temp_obj.set_type(dest_type); + temp_obj.set_collation_type(dst_collation); + temp_obj.set_scale(scale); if (ob_is_number_or_decimal_int_tc(dest_type)) { - tmp_obj.set_null(); + temp_obj.set_null(); } else { - tmp_obj.set_min_value(); + temp_obj.set_min_value(); } int64_t pos = str_buff.length(); uint64_t reserve_len = 0; - if (FALSE_IT(reserve_len = tmp_obj.get_serialize_size())) { + if (FALSE_IT(reserve_len = temp_obj.get_serialize_size())) { } else if (OB_FAIL(str_buff.reserve(reserve_len + 128))) { LOG_WARN("failed to reserve size", K(ret), K(reserve_len)); - } else if (OB_FAIL(tmp_obj.serialize(str_buff.ptr(), str_buff.capacity(), pos))) { + } else if (OB_FAIL(temp_obj.serialize(str_buff.ptr(), str_buff.capacity(), pos))) { LOG_WARN("failed to serialize datum", K(ret), K(reserve_len)); } else { str_buff.set_length(pos); } } - if (OB_SUCC(ret)) { + if (OB_FAIL(ret)) { + } else if (!is_result_array) { + ObObjDatumMapType type = ObDatum::get_obj_datum_map_type(dest_type); + if (element_count == 0) { + res.set_null(); + } else if (OB_ISNULL(object_ptr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed get object", K(ret)); + } else if (OB_FAIL(res.from_obj(*object_ptr, type))) { + LOG_WARN("failed from object", K(ret), K(*object_ptr)); + } + } else { apaque.set_value(str_buff.string()); if (OB_FAIL(apaque.get_raw_binary(str_bin, &allocator))) { LOG_WARN("json extarct get result binary failed", K(ret)); @@ -641,7 +639,7 @@ int ObExprJsonQuery::init_ctx_var(ObJsonParamCacheCtx*& param_ctx, ObEvalCtx &ct // parse asis if (OB_FAIL(ObJsonExprHelper::get_clause_opt(expr.args_[JSN_QUE_ASIS], ctx, val))) { LOG_WARN("fail to get clause option", K(ret)); - } else if (FALSE_IT(param_ctx->json_param_.is_alias_ = val)) { + } else if (FALSE_IT(param_ctx->json_param_.is_asis_ = val)) { } else if (OB_NOT_NULL(info) && OB_FAIL(extract_plan_cache_param(info, param_ctx->json_param_))) { LOG_WARN("fail to extract param from plan cache", K(ret)); @@ -750,7 +748,7 @@ int ObExprJsonQuery::check_params_valid(const ObExpr &expr, json_param->dst_type_, expr.datum_meta_.cs_type_, JSON_QUERY_EXPR))) { is_cover_by_error = false; LOG_WARN("check item func with return type fail", K(ret)); - } else if ( !json_param->is_alias_ + } else if ( !json_param->is_asis_ &&json_param->dst_type_ != ObVarcharType && json_param->dst_type_ != ObLongTextType && json_param->dst_type_ != ObJsonType) { @@ -819,7 +817,7 @@ int ObExprJsonQuery::get_clause_param_value(const ObExpr &expr, json_param->empty_type_ = param_vec[JSN_QUE_EMPTY_OPT]; json_param->on_mismatch_.push_back(param_vec[JSN_QUE_MISMATCH_OPT]); // ToDo: double check - json_param->is_alias_ = param_vec[JSN_QUE_ASIS_OPT] > 0; + json_param->is_asis_ = param_vec[JSN_QUE_ASIS_OPT] > 0; json_param->is_multivalue_ = param_vec[JSN_QUE_MULTIVALUE_OPT] > 0; if (json_param->is_multivalue_) { json_param->dst_type_ = ObJsonType; @@ -862,7 +860,7 @@ int ObExprJsonQuery::doc_do_seek(ObIJsonBase* j_base, is_null_result = true; } } else { - if (json_param->is_multivalue_ && json_param->json_path_->can_match_many()) { + if (json_param->is_asis_ && json_param->json_path_->can_match_many()) { use_wrapper = 1; } else if (OB_FAIL(get_single_obj_wrapper(json_param->wrapper_, use_wrapper, hits[0]->json_type(), json_param->scalars_type_))) { is_cover_by_error = true; @@ -883,7 +881,7 @@ int ObExprJsonQuery::doc_do_seek(ObIJsonBase* j_base, } } else if (hits.size() > 1) { // return val decide by wrapper option - if (json_param->is_multivalue_) { + if (json_param->is_asis_) { use_wrapper = 1; } else if (OB_FAIL(get_multi_scalars_wrapper_type(json_param->wrapper_, use_wrapper))) { is_cover_by_error = true; diff --git a/src/sql/engine/expr/ob_expr_json_query.h b/src/sql/engine/expr/ob_expr_json_query.h index a9b3386e12..8dfe3638dc 100644 --- a/src/sql/engine/expr/ob_expr_json_query.h +++ b/src/sql/engine/expr/ob_expr_json_query.h @@ -66,7 +66,8 @@ private: ObEvalCtx& ctx, ObObjType &dest_type, bool &is_cover_by_error); - static int set_multivalue_result(ObEvalCtx& ctx, + static int set_multivalue_result(bool is_array, + ObEvalCtx& ctx, ObIAllocator& allocator, ObIJsonBase* json_base, const ObExpr &expr,