Fixed the correctness issue of the LIKE expression when sql mode=NO_BACKSLASH_ESCAPES_LIKE.
This commit is contained in:
		@ -463,7 +463,9 @@ int ObExprLike::calc_escape_wc(const ObCollationType escape_coll,
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  size_t length = ObCharset::strlen_char(escape_coll, escape.ptr(),
 | 
			
		||||
                                         escape.length());
 | 
			
		||||
  if (1 != length) {
 | 
			
		||||
  if (0 == length) {
 | 
			
		||||
    escape_wc = -1;
 | 
			
		||||
  } else if (1 != length) {
 | 
			
		||||
    ret = OB_INVALID_ARGUMENT;
 | 
			
		||||
    LOG_WARN("invalid argument to ESCAPE", K(escape), K(length), K(ret));
 | 
			
		||||
  } else if (OB_FAIL(ObCharset::mb_wc(escape_coll, escape, escape_wc))) {
 | 
			
		||||
@ -671,13 +673,15 @@ int ObExprLike::like_varchar_inner(const ObExpr &expr, ObEvalCtx &ctx,  ObDatum
 | 
			
		||||
    ObString text_val = text.get_string();
 | 
			
		||||
    ObString pattern_val = pattern.get_string();
 | 
			
		||||
    ObString escape_val;
 | 
			
		||||
    if (escape.is_null()) {
 | 
			
		||||
      escape_val.assign_ptr("\\", 1);
 | 
			
		||||
    } else {
 | 
			
		||||
      escape_val = escape.get_string();
 | 
			
		||||
      if (escape_val.empty()) {
 | 
			
		||||
    if (escape.is_null() || escape.get_string().empty()) {
 | 
			
		||||
      bool is_no_backslash_escapes = false;
 | 
			
		||||
      IS_NO_BACKSLASH_ESCAPES(ctx.exec_ctx_.get_my_session()->get_sql_mode(),
 | 
			
		||||
                              is_no_backslash_escapes);
 | 
			
		||||
      if (!is_no_backslash_escapes) {
 | 
			
		||||
        escape_val.assign_ptr("\\", 1);
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      escape_val = escape.get_string();
 | 
			
		||||
    }
 | 
			
		||||
    if (do_optimization
 | 
			
		||||
        && like_id != OB_INVALID_ID
 | 
			
		||||
@ -1026,7 +1030,12 @@ int ObExprLike::like_text_vectorized_inner(const ObExpr &expr, ObEvalCtx &ctx,
 | 
			
		||||
    // check pattern is not null already, so result is null if and only if text is null.
 | 
			
		||||
    bool null_check = !expr.args_[0]->get_eval_info(ctx).notnull_;
 | 
			
		||||
    if (escape_datum->is_null() || escape_datum->get_string().empty()) {
 | 
			
		||||
      escape_val.assign_ptr("\\", 1);
 | 
			
		||||
      bool is_no_backslash_escapes = false;
 | 
			
		||||
      IS_NO_BACKSLASH_ESCAPES(ctx.exec_ctx_.get_my_session()->get_sql_mode(),
 | 
			
		||||
                              is_no_backslash_escapes);
 | 
			
		||||
      if (!is_no_backslash_escapes) {
 | 
			
		||||
        escape_val.assign_ptr("\\", 1);
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      escape_val = escape_datum->get_string();
 | 
			
		||||
    }
 | 
			
		||||
@ -1140,7 +1149,12 @@ int ObExprLike::like_text_vectorized_inner_vec2(const ObExpr &expr, ObEvalCtx &c
 | 
			
		||||
    // check pattern is not null already, so result is null if and only if text is null.
 | 
			
		||||
    bool null_check = !expr.args_[0]->get_eval_info(ctx).notnull_;
 | 
			
		||||
    if (escape_vector->is_null(0) || escape_vector->get_string(0).empty()) {
 | 
			
		||||
      escape_val.assign_ptr("\\", 1);
 | 
			
		||||
      bool is_no_backslash_escapes = false;
 | 
			
		||||
      IS_NO_BACKSLASH_ESCAPES(ctx.exec_ctx_.get_my_session()->get_sql_mode(),
 | 
			
		||||
                              is_no_backslash_escapes);
 | 
			
		||||
      if (!is_no_backslash_escapes) {
 | 
			
		||||
        escape_val.assign_ptr("\\", 1);
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      escape_val = escape_vector->get_string(0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -3734,6 +3734,14 @@ int ObRawExprResolverImpl::process_like_node(const ParseNode *node, ObRawExpr *&
 | 
			
		||||
      escape_node.text_len_ = 0;
 | 
			
		||||
      escape_node.raw_text_ = NULL;
 | 
			
		||||
 | 
			
		||||
      // when sql_mode = 'NO_BACKSLASH_ESCAPES', Remove the default value '\'.
 | 
			
		||||
      // otherwise, it is not possible to determine whether ESCAPE is explicitly specified.
 | 
			
		||||
      bool is_no_backslash_escapes = false;
 | 
			
		||||
      IS_NO_BACKSLASH_ESCAPES(ctx_.session_info_->get_sql_mode(), is_no_backslash_escapes);
 | 
			
		||||
      if (lib::is_mysql_mode() && is_no_backslash_escapes) {
 | 
			
		||||
        escape_node.str_len_ = 0;
 | 
			
		||||
        escape_node.str_value_ = "";
 | 
			
		||||
      }
 | 
			
		||||
      /*
 | 
			
		||||
      bugfix:
 | 
			
		||||
      in NO_BACKSLASH_ESCAPES mode, 'like BINARY xxx' stmt should also set the escapes as null, instead of '\' 
 | 
			
		||||
@ -3745,7 +3753,7 @@ int ObRawExprResolverImpl::process_like_node(const ParseNode *node, ObRawExpr *&
 | 
			
		||||
          && node->children_[1]->children_[1]->num_child_ == 2 // T_EXPR_LIST node
 | 
			
		||||
          && node->children_[1]->children_[1]->children_[1]->int16_values_[OB_NODE_CAST_TYPE_IDX] == T_VARCHAR
 | 
			
		||||
          && node->children_[1]->children_[1]->children_[1]->int16_values_[OB_NODE_CAST_COLL_IDX] == BINARY_COLLATION) {
 | 
			
		||||
        IS_NO_BACKSLASH_ESCAPES(ctx_.session_info_->get_sql_mode(), no_escapes);
 | 
			
		||||
        no_escapes = is_no_backslash_escapes;
 | 
			
		||||
      }
 | 
			
		||||
      if (OB_FAIL(process_datatype_or_questionmark(escape_node, escape_expr))) {
 | 
			
		||||
        LOG_WARN("fail to resolver default excape node", K(ret));
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user