[CP] fix like(nchar) bug
This commit is contained in:
		| @ -208,16 +208,15 @@ int ObExprLike::check_pattern_valid(const T &pattern, | |||||||
|       } else if (pre_char_is_escape) { |       } else if (pre_char_is_escape) { | ||||||
|         // If pre char is escape char, then the following char must be '_' or '%' |         // If pre char is escape char, then the following char must be '_' or '%' | ||||||
|         // Eg: select 1 from t1 where 'a' like 'a_a%' escape 'a'; -- it's ok |         // Eg: select 1 from t1 where 'a' like 'a_a%' escape 'a'; -- it's ok | ||||||
|         if (1 != char_len) { |         ObString percent_str = ObCharsetUtils::get_const_str(coll_type, '%'); | ||||||
|           ret = OB_ERR_INVALID_CHAR_FOLLOWING_ESCAPE_CHAR; |         ObString underline_str = ObCharsetUtils::get_const_str(coll_type, '_'); | ||||||
|           LOG_WARN("missing or illegal character following the escape character", |         const ObString pattern_char = ObString(char_len, buf_start); | ||||||
|                    K(escape_val), K(pattern_val), K(ret)); |         if (0 == pattern_char.compare(percent_str) || 0 == pattern_char.compare(underline_str)) { | ||||||
|         } else if ('%' == *buf_start || '_' == *buf_start) { |  | ||||||
|           // it's ok |           // it's ok | ||||||
|         } else { |         } else { | ||||||
|           ret = OB_ERR_INVALID_CHAR_FOLLOWING_ESCAPE_CHAR; |           ret = OB_ERR_INVALID_CHAR_FOLLOWING_ESCAPE_CHAR; | ||||||
|           LOG_WARN("missing or illegal character following the escape character", |           LOG_WARN("missing or illegal character following the escape character", | ||||||
|                     K(escape_val), K(pattern_val), K(ret)); |                     K(escape_val), K(pattern_val), K(pattern_char), K(ret)); | ||||||
|         } |         } | ||||||
|         pre_char_is_escape = false; |         pre_char_is_escape = false; | ||||||
|       } |       } | ||||||
| @ -361,6 +360,7 @@ int ObExprLike::set_instr_info(ObIAllocator *exec_allocator, | |||||||
|           //when there are "_" or escape in pattern |           //when there are "_" or escape in pattern | ||||||
|           //the case can not be optimized. |           //the case can not be optimized. | ||||||
|           use_instr_mode = false; |           use_instr_mode = false; | ||||||
|  |         // since cs_type is CS_TYPE_UTF8MB4_BIN, length of '%' must be 1. | ||||||
|         } else if ((1 == char_len && '%' == *buf_start)) { //percent sign |         } else if ((1 == char_len && '%' == *buf_start)) { //percent sign | ||||||
|           percent_sign_exist = true; |           percent_sign_exist = true; | ||||||
|           if (OB_LIKELY(instr_len > 0)) { |           if (OB_LIKELY(instr_len > 0)) { | ||||||
| @ -822,12 +822,16 @@ struct ObNonInstrModeMatcher | |||||||
|   inline int64_t operator() (const ObCollationType coll_type, |   inline int64_t operator() (const ObCollationType coll_type, | ||||||
|                         const ObString &text_val, |                         const ObString &text_val, | ||||||
|                         const ObString &pattern_val, |                         const ObString &pattern_val, | ||||||
|                         int32_t escape_wc) |                         int32_t escape_wc, | ||||||
|  |                         int &ret) | ||||||
|   { |   { | ||||||
|     int64_t res = 0; |     int64_t res = 0; | ||||||
|     if (OB_UNLIKELY(text_val.length() <= 0 && pattern_val.length() <= 0)) { |     if (OB_UNLIKELY(text_val.length() <= 0 && pattern_val.length() <= 0)) { | ||||||
|       // empty string |       // empty string | ||||||
|       res = 1; |       res = 1; | ||||||
|  |     } else if (OB_UNLIKELY(CS_TYPE_UTF8MB4_BIN != coll_type && escape_wc == static_cast<int32_t>('%'))) { | ||||||
|  |       ret = OB_NOT_SUPPORTED; | ||||||
|  |       LOG_USER_ERROR(OB_NOT_SUPPORTED, "escape %"); | ||||||
|     } else { |     } else { | ||||||
|       bool b = ObCharset::wildcmp(coll_type, text_val, pattern_val, escape_wc, |       bool b = ObCharset::wildcmp(coll_type, text_val, pattern_val, escape_wc, | ||||||
|                                   static_cast<int32_t>('_'), static_cast<int32_t>('%')); |                                   static_cast<int32_t>('_'), static_cast<int32_t>('%')); | ||||||
| @ -867,7 +871,7 @@ int ObExprLike::match_text_batch(BATCH_EVAL_FUNC_ARG_DECL, | |||||||
|             res_datums[i].set_int(res); |             res_datums[i].set_int(res); | ||||||
|           } else { |           } else { | ||||||
|             res_datums[i].set_int(ObNonInstrModeMatcher()(coll_type, text_datums[i].get_string(), |             res_datums[i].set_int(ObNonInstrModeMatcher()(coll_type, text_datums[i].get_string(), | ||||||
|                                                           pattern_val, escape_wc)); |                                                           pattern_val, escape_wc, ret)); | ||||||
|           } |           } | ||||||
|         } else { // text tc |         } else { // text tc | ||||||
|           ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx); |           ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx); | ||||||
| @ -886,7 +890,7 @@ int ObExprLike::match_text_batch(BATCH_EVAL_FUNC_ARG_DECL, | |||||||
|             res_datums[i].set_int(res); |             res_datums[i].set_int(res); | ||||||
|           } else { |           } else { | ||||||
|             res_datums[i].set_int(ObNonInstrModeMatcher()(coll_type, text_val, |             res_datums[i].set_int(ObNonInstrModeMatcher()(coll_type, text_val, | ||||||
|                                                           pattern_val, escape_wc)); |                                                           pattern_val, escape_wc, ret)); | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
| @ -909,7 +913,7 @@ int ObExprLike::match_text_batch(BATCH_EVAL_FUNC_ARG_DECL, | |||||||
|               res_datums[i].set_int(res); |               res_datums[i].set_int(res); | ||||||
|             } else { |             } else { | ||||||
|               res_datums[i].set_int(ObNonInstrModeMatcher()(coll_type, text_datums[i].get_string(), |               res_datums[i].set_int(ObNonInstrModeMatcher()(coll_type, text_datums[i].get_string(), | ||||||
|                                                             pattern_val, escape_wc)); |                                                             pattern_val, escape_wc, ret)); | ||||||
|             } |             } | ||||||
|           } else { // text tc |           } else { // text tc | ||||||
|             ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx); |             ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx); | ||||||
| @ -929,7 +933,7 @@ int ObExprLike::match_text_batch(BATCH_EVAL_FUNC_ARG_DECL, | |||||||
|                 res_datums[i].set_int(res); |                 res_datums[i].set_int(res); | ||||||
|               } else { |               } else { | ||||||
|                 res_datums[i].set_int(ObNonInstrModeMatcher()(coll_type, text_val, |                 res_datums[i].set_int(ObNonInstrModeMatcher()(coll_type, text_val, | ||||||
|                                                               pattern_val, escape_wc)); |                                                               pattern_val, escape_wc, ret)); | ||||||
|               } |               } | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|  | |||||||
| @ -229,9 +229,15 @@ int ObExprLike::calc_with_non_instr_mode(T &result, | |||||||
|   } else if (text_val.length() <= 0 && pattern_val.length() <= 0) { |   } else if (text_val.length() <= 0 && pattern_val.length() <= 0) { | ||||||
|     // empty string |     // empty string | ||||||
|     result.set_int(1); |     result.set_int(1); | ||||||
|  |   } else if (OB_UNLIKELY(CS_TYPE_UTF8MB4_BIN != coll_type && escape_wc == static_cast<int32_t>('%'))) { | ||||||
|  |     // when cs_type is not utf8mb4_bin and escape = %, there is a bug of wildcmp | ||||||
|  |     ret = OB_NOT_SUPPORTED; | ||||||
|  |     LOG_USER_ERROR(OB_NOT_SUPPORTED, "escape %"); | ||||||
|   } else { |   } else { | ||||||
|     bool b = ObCharset::wildcmp(coll_type, text_val, pattern_val, escape_wc, |     bool b = ObCharset::wildcmp(coll_type, text_val, pattern_val, escape_wc, | ||||||
|                                 static_cast<int32_t>('_'), static_cast<int32_t>('%')); |                                 static_cast<int32_t>('_'), static_cast<int32_t>('%')); | ||||||
|  |     SQL_LOG(DEBUG, "calc_with_non_instr_mode1", K(escape_coll), K(escape_val), K(escape_wc), K(pattern_val), | ||||||
|  |              K(coll_type), KPHEX(text_val.ptr(), text_val.length()), KPHEX(pattern_val.ptr(), pattern_val.length()), K(b)); | ||||||
|     result.set_int(static_cast<int64_t>(b)); |     result.set_int(static_cast<int64_t>(b)); | ||||||
|   } |   } | ||||||
|   return ret; |   return ret; | ||||||
|  | |||||||
| @ -7506,8 +7506,7 @@ int ObQueryRange::get_like_range(const ObObj &pattern, | |||||||
|     } else if (OB_ISNULL(escape_str.ptr())) { |     } else if (OB_ISNULL(escape_str.ptr())) { | ||||||
|       ret = OB_ERR_UNEXPECTED; |       ret = OB_ERR_UNEXPECTED; | ||||||
|       LOG_WARN("Escape str should not be NULL", K(ret)); |       LOG_WARN("Escape str should not be NULL", K(ret)); | ||||||
|     } else if (OB_UNLIKELY((lib::is_oracle_mode() && 1 != escape_str.length()) |     } else if (OB_UNLIKELY(1 > escape_str.length())) { | ||||||
|      || (!lib::is_oracle_mode() && 1 > escape_str.length()))) { |  | ||||||
|       ret = OB_INVALID_ARGUMENT; |       ret = OB_INVALID_ARGUMENT; | ||||||
|       LOG_WARN("failed to check escape length", K(escape_str), K(escape_str.length())); |       LOG_WARN("failed to check escape length", K(escape_str), K(escape_str.length())); | ||||||
|       LOG_USER_ERROR(OB_INVALID_ARGUMENT, "ESCAPE"); |       LOG_USER_ERROR(OB_INVALID_ARGUMENT, "ESCAPE"); | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 sdc
					sdc