fix row query range bug
This commit is contained in:
		| @ -2006,7 +2006,9 @@ int ObQueryRange::get_row_key_part(const ObRawExpr *l_expr, | |||||||
|         ret = OB_ERR_UNEXPECTED; |         ret = OB_ERR_UNEXPECTED; | ||||||
|         LOG_WARN("get unexpected null", K(ret)); |         LOG_WARN("get unexpected null", K(ret)); | ||||||
|       } else if (tmp_key_part->is_always_false()) { |       } else if (tmp_key_part->is_always_false()) { | ||||||
|  |         if (i == 0) { | ||||||
|           out_key_part = tmp_key_part; |           out_key_part = tmp_key_part; | ||||||
|  |         } | ||||||
|         b_flag = true; |         b_flag = true; | ||||||
|       } else if (T_OP_EQ == cmp_type || T_OP_NSEQ == cmp_type) { |       } else if (T_OP_EQ == cmp_type || T_OP_NSEQ == cmp_type) { | ||||||
|         row_is_precise = (row_is_precise && query_range_ctx_->cur_expr_is_precise_); |         row_is_precise = (row_is_precise && query_range_ctx_->cur_expr_is_precise_); | ||||||
| @ -2034,7 +2036,7 @@ int ObQueryRange::get_row_key_part(const ObRawExpr *l_expr, | |||||||
|         row_tail = tmp_key_part; |         row_tail = tmp_key_part; | ||||||
|         normal_key_cnt += 1; |         normal_key_cnt += 1; | ||||||
|         const ObRawExpr *const_expr = l_expr->is_const_expr() ? l_expr : r_expr; |         const ObRawExpr *const_expr = l_expr->is_const_expr() ? l_expr : r_expr; | ||||||
|         if (OB_FAIL(check_bound(tmp_key_part, dtc_params, const_expr, is_bound_modified))) { |         if (OB_FAIL(check_row_bound(tmp_key_part, dtc_params, const_expr, is_bound_modified))) { | ||||||
|           LOG_WARN("failed to check bound modified"); |           LOG_WARN("failed to check bound modified"); | ||||||
|         } else if (is_bound_modified) { |         } else if (is_bound_modified) { | ||||||
|           b_flag = true; |           b_flag = true; | ||||||
| @ -2063,51 +2065,31 @@ int ObQueryRange::get_row_key_part(const ObRawExpr *l_expr, | |||||||
|   return ret; |   return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
| int ObQueryRange::check_bound(ObKeyPart *key_part, | int ObQueryRange::check_row_bound(ObKeyPart *key_part, | ||||||
|                               const ObDataTypeCastParams &dtc_params, |                               const ObDataTypeCastParams &dtc_params, | ||||||
|                               const ObRawExpr *const_expr, |                               const ObRawExpr *const_expr, | ||||||
|                               bool &is_bound_modified) |                               bool &is_bound_modified) | ||||||
| { | { | ||||||
|   int ret = OB_SUCCESS; |   int ret = OB_SUCCESS; | ||||||
|  |   ObObj const_val; | ||||||
|  |   bool is_valid = false; | ||||||
|  |   int64_t cmp = 0; | ||||||
|   if (OB_ISNULL(key_part) || OB_ISNULL(query_range_ctx_) || OB_ISNULL(const_expr)) { |   if (OB_ISNULL(key_part) || OB_ISNULL(query_range_ctx_) || OB_ISNULL(const_expr)) { | ||||||
|     ret = OB_ERR_UNEXPECTED; |     ret = OB_ERR_UNEXPECTED; | ||||||
|     LOG_WARN("get unexpected null", K(ret), K(key_part), K(query_range_ctx_), K(const_expr)); |     LOG_WARN("get unexpected null", K(ret), K(key_part), K(query_range_ctx_), K(const_expr)); | ||||||
|   } else if (key_part->is_question_mark() && query_range_ctx_->exec_ctx_ != NULL) { |   } else if (OB_FAIL(get_calculable_expr_val(const_expr, const_val, is_valid))) { | ||||||
|     ObObj tmp; |     LOG_WARN("failed to calculate val", K(ret), K(*const_expr), K(const_val), K(is_valid)); | ||||||
|     int64_t start_cmp = 0; |  | ||||||
|     int64_t end_cmp = 0; |  | ||||||
|     bool is_valid = false; |  | ||||||
|     if (key_part->normal_keypart_->start_.is_unknown()) { |  | ||||||
|       if (OB_FAIL(ob_write_obj(allocator_, key_part->normal_keypart_->start_, tmp))) { |  | ||||||
|         LOG_WARN("failed to deep copy obj", K(ret)); |  | ||||||
|       } else if (OB_FAIL(get_calculable_expr_val(const_expr, tmp, is_valid))) { |  | ||||||
|         LOG_WARN("failed to calculate val", K(ret), K(*const_expr), K(tmp), K(is_valid)); |  | ||||||
|   } else if (!is_valid) { |   } else if (!is_valid) { | ||||||
|     // do nothing |     // do nothing | ||||||
|   } else if (OB_FAIL(ObKeyPart::try_cast_value(dtc_params, allocator_, key_part->pos_, |   } else if (OB_FAIL(ObKeyPart::try_cast_value(dtc_params, allocator_, key_part->pos_, | ||||||
|                                                     tmp, start_cmp))) { |                                                 const_val, cmp))) { | ||||||
|     LOG_WARN("failed to cast value", K(ret)); |     LOG_WARN("failed to cast value", K(ret)); | ||||||
|       } |   } else if (cmp != 0 || ob_obj_type_class(const_expr->get_data_type()) != | ||||||
|     } |                          ob_obj_type_class(key_part->pos_.column_type_.get_type())) { | ||||||
|     if (OB_SUCC(ret) && key_part->normal_keypart_->end_.is_unknown()) { |  | ||||||
|       if (OB_FAIL(ob_write_obj(allocator_, key_part->normal_keypart_->end_, tmp))) { |  | ||||||
|         LOG_WARN("failed to deep copy obj", K(ret)); |  | ||||||
|       } else if (OB_FAIL(get_calculable_expr_val(const_expr, tmp, is_valid))) { |  | ||||||
|         LOG_WARN("failed to calculate val", K(ret), K(*const_expr), K(tmp), K(is_valid)); |  | ||||||
|       } else if (!is_valid) { |  | ||||||
|         // do nothing |  | ||||||
|       } else if (OB_FAIL(ObKeyPart::try_cast_value(dtc_params, allocator_, key_part->pos_, |  | ||||||
|                                                     tmp, end_cmp))) { |  | ||||||
|         LOG_WARN("failed to cast value", K(ret)); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     if (OB_SUCC(ret) && (start_cmp != 0 || end_cmp != 0)) { |  | ||||||
|       // the bound will be modified after we replace the unknown value at final stage |  | ||||||
|     is_bound_modified = true; |     is_bound_modified = true; | ||||||
|   } |   } | ||||||
|   LOG_TRACE("succeed to check bound", |   LOG_TRACE("succeed to check bound", | ||||||
|               K(is_bound_modified), K(start_cmp), K(end_cmp), K(tmp), K(*key_part), K(*const_expr)); |             K(is_bound_modified), K(cmp), K(is_valid), K(*key_part), K(*const_expr), K(const_val)); | ||||||
|   } |  | ||||||
|   return ret; |   return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -5175,14 +5157,16 @@ int ObQueryRange::link_or_graphs(ObKeyPartList &storage, ObKeyPart  *&out_key_pa | |||||||
| // Replace unknown value in item_next_ list, | // Replace unknown value in item_next_ list, | ||||||
| // and intersect them. | // and intersect them. | ||||||
|  |  | ||||||
| int ObQueryRange::definite_key_part(ObKeyPart *&key_part, ObExecContext &exec_ctx, const ObDataTypeCastParams &dtc_params) | int ObQueryRange::definite_key_part(ObKeyPart *&key_part, ObExecContext &exec_ctx, | ||||||
|  |                                     const ObDataTypeCastParams &dtc_params, | ||||||
|  |                                     bool &is_bound_modified) | ||||||
| { | { | ||||||
|   int ret = OB_SUCCESS; |   int ret = OB_SUCCESS; | ||||||
|   if (NULL != key_part) { |   if (NULL != key_part) { | ||||||
|     for (ObKeyPart *cur = key_part; |     for (ObKeyPart *cur = key_part; | ||||||
|          OB_SUCC(ret) && NULL != cur; |          OB_SUCC(ret) && NULL != cur; | ||||||
|          cur = cur->item_next_) { |          cur = cur->item_next_) { | ||||||
|       if (OB_FAIL(replace_unknown_value(cur, exec_ctx, dtc_params))) { |       if (OB_FAIL(replace_unknown_value(cur, exec_ctx, dtc_params, is_bound_modified))) { | ||||||
|         LOG_WARN("Replace unknown value failed", K(ret)); |         LOG_WARN("Replace unknown value failed", K(ret)); | ||||||
|       } else if (cur->is_always_false()) { // set key_part false |       } else if (cur->is_always_false()) { // set key_part false | ||||||
|         key_part->normal_keypart_ = cur->normal_keypart_; |         key_part->normal_keypart_ = cur->normal_keypart_; | ||||||
| @ -5309,8 +5293,9 @@ int ObQueryRange::or_single_head_graphs(ObKeyPartList &or_list, | |||||||
|         ObKeyPart *new_tmp = cur; |         ObKeyPart *new_tmp = cur; | ||||||
|         ObKeyPart *and_next = cur->and_next_; |         ObKeyPart *and_next = cur->and_next_; | ||||||
|         cur = cur->get_next(); |         cur = cur->get_next(); | ||||||
|  |         bool is_bound_modified = false; | ||||||
|         // replace undefinited value |         // replace undefinited value | ||||||
|         if (OB_FAIL(definite_key_part(new_tmp, *exec_ctx, dtc_params))) { |         if (OB_FAIL(definite_key_part(new_tmp, *exec_ctx, dtc_params, is_bound_modified))) { | ||||||
|           LOG_WARN("Fill unknown value failed", K(ret)); |           LOG_WARN("Fill unknown value failed", K(ret)); | ||||||
|         } else if (new_tmp != old_tmp) { |         } else if (new_tmp != old_tmp) { | ||||||
|           old_tmp->replace_by(new_tmp); |           old_tmp->replace_by(new_tmp); | ||||||
| @ -5338,7 +5323,10 @@ int ObQueryRange::or_single_head_graphs(ObKeyPartList &or_list, | |||||||
|             } |             } | ||||||
|           } else { |           } else { | ||||||
|             // handle the rest of the graph recursively |             // handle the rest of the graph recursively | ||||||
|             if (NULL != and_next) { |             if (contain_row_ && is_bound_modified) { | ||||||
|  |               and_next = NULL; | ||||||
|  |               new_tmp->and_next_ = NULL; | ||||||
|  |             } else if (NULL != and_next) { | ||||||
|               // recursively process following and key part |               // recursively process following and key part | ||||||
|               ObKeyPartList sub_or_list; |               ObKeyPartList sub_or_list; | ||||||
|               if (OB_FAIL(split_or(and_next, sub_or_list))) { |               if (OB_FAIL(split_or(and_next, sub_or_list))) { | ||||||
| @ -5698,6 +5686,7 @@ int ObQueryRange::definite_in_range_graph(ObExecContext &exec_ctx, | |||||||
| { | { | ||||||
|   int ret = OB_SUCCESS; |   int ret = OB_SUCCESS; | ||||||
|   bool is_stack_overflow = false; |   bool is_stack_overflow = false; | ||||||
|  |   bool is_bound_modified = false; | ||||||
|   if (OB_FAIL(THIS_WORKER.check_status())) { |   if (OB_FAIL(THIS_WORKER.check_status())) { | ||||||
|     LOG_WARN("check status fail", K(ret)); |     LOG_WARN("check status fail", K(ret)); | ||||||
|   } else if (OB_FAIL(check_stack_overflow(is_stack_overflow))) { |   } else if (OB_FAIL(check_stack_overflow(is_stack_overflow))) { | ||||||
| @ -5708,9 +5697,12 @@ int ObQueryRange::definite_in_range_graph(ObExecContext &exec_ctx, | |||||||
|   } else if (OB_ISNULL(root)) { |   } else if (OB_ISNULL(root)) { | ||||||
|     ret = OB_INVALID_ARGUMENT; |     ret = OB_INVALID_ARGUMENT; | ||||||
|     LOG_WARN("root key is null", K(root)); |     LOG_WARN("root key is null", K(root)); | ||||||
|   } else if (OB_FAIL(definite_key_part(root, exec_ctx, dtc_params))) { |   } else if (OB_FAIL(definite_key_part(root, exec_ctx, dtc_params, is_bound_modified))) { | ||||||
|     LOG_WARN("definite key part failed", K(ret)); |     LOG_WARN("definite key part failed", K(ret)); | ||||||
|   } else { |   } else { | ||||||
|  |     if (contain_row_ && is_bound_modified) { | ||||||
|  |       root->and_next_ = NULL; | ||||||
|  |     } | ||||||
|     //如果graph中某个节点不是严格的等值条件,那么这个节点是一个scan key,需要做or合并 |     //如果graph中某个节点不是严格的等值条件,那么这个节点是一个scan key,需要做or合并 | ||||||
|     //如果有恒false条件,也需要走到or去做去除处理 |     //如果有恒false条件,也需要走到or去做去除处理 | ||||||
|     if (!root->is_equal_condition()) { |     if (!root->is_equal_condition()) { | ||||||
| @ -7221,7 +7213,9 @@ OB_NOINLINE int ObQueryRange::final_extract_query_range(ObExecContext &exec_ctx, | |||||||
| } | } | ||||||
| #undef FINAL_EXTRACT | #undef FINAL_EXTRACT | ||||||
|  |  | ||||||
| int ObQueryRange::replace_unknown_value(ObKeyPart *root, ObExecContext &exec_ctx, const ObDataTypeCastParams &dtc_params) | int ObQueryRange::replace_unknown_value(ObKeyPart *root, ObExecContext &exec_ctx, | ||||||
|  |                                         const ObDataTypeCastParams &dtc_params, | ||||||
|  |                                         bool &is_bound_modified) | ||||||
| { | { | ||||||
|   int ret = OB_SUCCESS; |   int ret = OB_SUCCESS; | ||||||
|   bool is_inconsistent_rowid = false; |   bool is_inconsistent_rowid = false; | ||||||
| @ -7340,10 +7334,9 @@ int ObQueryRange::replace_unknown_value(ObKeyPart *root, ObExecContext &exec_ctx | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   if (OB_SUCC(ret)) { |   if (OB_SUCC(ret)) { | ||||||
|     bool dummy_is_bound_modified = false; |  | ||||||
|     if (root->is_phy_rowid_key_part() || root->is_in_key()) { |     if (root->is_phy_rowid_key_part() || root->is_in_key()) { | ||||||
|       ////physical rowid no need cast, it's will be transformed in table scan phase. |       ////physical rowid no need cast, it's will be transformed in table scan phase. | ||||||
|     } else if (OB_FAIL(root->cast_value_type(dtc_params, contain_row_, dummy_is_bound_modified))) { |     } else if (OB_FAIL(root->cast_value_type(dtc_params, contain_row_, is_bound_modified))) { | ||||||
|       LOG_WARN("cast value type failed", K(ret)); |       LOG_WARN("cast value type failed", K(ret)); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -590,7 +590,7 @@ private: | |||||||
|                        const ObExprResType &result_type, |                        const ObExprResType &result_type, | ||||||
|                        ObKeyPart *&out_key_part, |                        ObKeyPart *&out_key_part, | ||||||
|                        const common::ObDataTypeCastParams &dtc_params); |                        const common::ObDataTypeCastParams &dtc_params); | ||||||
|   int check_bound(ObKeyPart *key_part, |   int check_row_bound(ObKeyPart *key_part, | ||||||
|                   const ObDataTypeCastParams &dtc_params, |                   const ObDataTypeCastParams &dtc_params, | ||||||
|                   const ObRawExpr *const_expr, |                   const ObRawExpr *const_expr, | ||||||
|                   bool &is_bound_modified); |                   bool &is_bound_modified); | ||||||
| @ -715,9 +715,11 @@ private: | |||||||
|   int do_gt_and(ObKeyPart *l_gt, ObKeyPart *r_gt, ObKeyPart *&res_gt); |   int do_gt_and(ObKeyPart *l_gt, ObKeyPart *r_gt, ObKeyPart *&res_gt); | ||||||
|   int link_or_graphs(ObKeyPartList &storage, ObKeyPart *&out_key_part); |   int link_or_graphs(ObKeyPartList &storage, ObKeyPart *&out_key_part); | ||||||
|   int definite_key_part(ObKeyPart *&key_part, ObExecContext &exec_ctx, |   int definite_key_part(ObKeyPart *&key_part, ObExecContext &exec_ctx, | ||||||
|                         const common::ObDataTypeCastParams &dtc_params); |                         const common::ObDataTypeCastParams &dtc_params, | ||||||
|  |                         bool &is_bound_modified); | ||||||
|   int replace_unknown_value(ObKeyPart *root, ObExecContext &exec_ctx, |   int replace_unknown_value(ObKeyPart *root, ObExecContext &exec_ctx, | ||||||
|                            const common::ObDataTypeCastParams &dtc_params); |                             const common::ObDataTypeCastParams &dtc_params, | ||||||
|  |                             bool &is_bound_modified); | ||||||
|   int or_single_head_graphs(ObKeyPartList &or_list, ObExecContext *exec_ctx, |   int or_single_head_graphs(ObKeyPartList &or_list, ObExecContext *exec_ctx, | ||||||
|                             const common::ObDataTypeCastParams &dtc_params, bool is_in_or = false); |                             const common::ObDataTypeCastParams &dtc_params, bool is_in_or = false); | ||||||
|   int union_in_with_in(ObKeyPartList &or_list, |   int union_in_with_in(ObKeyPartList &or_list, | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Larry955
					Larry955