fix some potential bugs
This commit is contained in:
		
				
					committed by
					
						
						wangzelin.wzl
					
				
			
			
				
	
			
			
			
						parent
						
							3107d410f1
						
					
				
				
					commit
					047132a3a7
				
			@ -689,11 +689,16 @@ int ObExprRegexContext::replace(const ObString& text, const ObString& to, ObSEAr
 | 
			
		||||
        if (OB_UNLIKELY(real_tot_length > tot_length)) {
 | 
			
		||||
          ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
          LOG_WARN("get invalid argument", K(real_tot_length), K(tot_length), K(ret));
 | 
			
		||||
        } else {
 | 
			
		||||
          char* real_buf = static_cast<char*>(string_buf.alloc(real_tot_length));
 | 
			
		||||
          MEMSET(real_buf, 0, real_tot_length);
 | 
			
		||||
          MEMCPY(real_buf, buf, real_tot_length);
 | 
			
		||||
          sub.assign_ptr(real_buf, static_cast<int64_t>(real_tot_length));
 | 
			
		||||
        } else if (real_tot_length > 0) {
 | 
			
		||||
          char *real_buf = static_cast<char *>(string_buf.alloc(real_tot_length));
 | 
			
		||||
          if (OB_ISNULL(real_buf)) {
 | 
			
		||||
            ret = OB_ALLOCATE_MEMORY_FAILED;
 | 
			
		||||
            LOG_WARN("alloc memory failed.", K(real_buf), K(ret));
 | 
			
		||||
          } else {
 | 
			
		||||
            MEMSET(real_buf, 0, real_tot_length);
 | 
			
		||||
            MEMCPY(real_buf, buf, real_tot_length);
 | 
			
		||||
            sub.assign_ptr(real_buf, static_cast<int64_t>(real_tot_length));
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@ -760,27 +765,32 @@ int ObExprRegexContext::w2c(
 | 
			
		||||
  if (length < 0 || (length > 0 && OB_ISNULL(wc))) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("source text is null or length is vaild", K(ret), K(wc), K(length));
 | 
			
		||||
  } else {
 | 
			
		||||
  } else if (length > 0) {
 | 
			
		||||
    int32_t buff_len = sizeof(wchar_t);
 | 
			
		||||
    char* buff = static_cast<char*>(string_buf.alloc(buff_len));
 | 
			
		||||
    int64_t chr_len = (length + 1) * buff_len;
 | 
			
		||||
    chr = static_cast<char*>(string_buf.alloc(chr_len));
 | 
			
		||||
    char* tmp_chr = chr;
 | 
			
		||||
    MEMSET(chr, 0, chr_len);
 | 
			
		||||
    MEMSET(buff, 0, buff_len);
 | 
			
		||||
    for (int64_t i = 0; OB_SUCC(ret) && i < length; ++i) {
 | 
			
		||||
      int32_t wc_int = static_cast<int32_t>(wc[i]);
 | 
			
		||||
      int32_t real_length = 0;
 | 
			
		||||
      if (OB_FAIL(ObCharset::wc_mb(
 | 
			
		||||
              ObCharset::get_default_collation_oracle(CHARSET_UTF8MB4), wc_int, buff, buff_len, real_length))) {
 | 
			
		||||
        LOG_WARN("failed to multi byte to wide char", K(ret));
 | 
			
		||||
      } else if (OB_UNLIKELY(chr_length + real_length > chr_len)) {
 | 
			
		||||
        ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
        LOG_WARN("get unexpected error", K(chr_length), K(real_length), K(chr_len), K(ret));
 | 
			
		||||
      } else {
 | 
			
		||||
        MEMCPY(tmp_chr, buff, real_length);
 | 
			
		||||
        chr_length += real_length;
 | 
			
		||||
        tmp_chr = tmp_chr + real_length;
 | 
			
		||||
    char *buff = NULL;
 | 
			
		||||
    if (OB_ISNULL(buff = static_cast<char *>(string_buf.alloc(buff_len))) ||
 | 
			
		||||
        OB_ISNULL(chr = static_cast<char *>(string_buf.alloc(chr_len)))) {
 | 
			
		||||
      ret = OB_ALLOCATE_MEMORY_FAILED;
 | 
			
		||||
      LOG_WARN("alloc memory failed.", K(buff), K(chr), K(ret));
 | 
			
		||||
    } else {
 | 
			
		||||
      char *tmp_chr = chr;
 | 
			
		||||
      MEMSET(chr, 0, chr_len);
 | 
			
		||||
      MEMSET(buff, 0, buff_len);
 | 
			
		||||
      for (int64_t i = 0; OB_SUCC(ret) && i < length; ++i) {
 | 
			
		||||
        int32_t wc_int = static_cast<int32_t>(wc[i]);
 | 
			
		||||
        int32_t real_length = 0;
 | 
			
		||||
        if (OB_FAIL(ObCharset::wc_mb(
 | 
			
		||||
                ObCharset::get_default_collation_oracle(CHARSET_UTF8MB4), wc_int, buff, buff_len, real_length))) {
 | 
			
		||||
          LOG_WARN("failed to multi byte to wide char", K(ret));
 | 
			
		||||
        } else if (OB_UNLIKELY(chr_length + real_length > chr_len)) {
 | 
			
		||||
          ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
          LOG_WARN("get unexpected error", K(chr_length), K(real_length), K(chr_len), K(ret));
 | 
			
		||||
        } else {
 | 
			
		||||
          MEMCPY(tmp_chr, buff, real_length);
 | 
			
		||||
          chr_length += real_length;
 | 
			
		||||
          tmp_chr = tmp_chr + real_length;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@ -926,10 +936,15 @@ int ObExprRegexContext::pre_process_replace_str(const ObString& text, const ObSt
 | 
			
		||||
            MEMCPY(tmp_buf, to_ptr + length_to - 1, 1);
 | 
			
		||||
            ++real_tot_length;
 | 
			
		||||
          }
 | 
			
		||||
          char* real_buf = static_cast<char*>(string_buf.alloc(real_tot_length));
 | 
			
		||||
          MEMSET(real_buf, 0, real_tot_length);
 | 
			
		||||
          MEMCPY(real_buf, buf, real_tot_length);
 | 
			
		||||
          tmp_string.assign_ptr(real_buf, static_cast<int64_t>(real_tot_length));
 | 
			
		||||
          char *real_buf = static_cast<char *>(string_buf.alloc(real_tot_length));
 | 
			
		||||
          if (OB_ISNULL(real_buf)) {
 | 
			
		||||
            ret = OB_ALLOCATE_MEMORY_FAILED;
 | 
			
		||||
            LOG_ERROR("alloc memory failed.", K(real_buf), K(ret));
 | 
			
		||||
          } else {
 | 
			
		||||
            MEMSET(real_buf, 0, real_tot_length);
 | 
			
		||||
            MEMCPY(real_buf, buf, real_tot_length);
 | 
			
		||||
            tmp_string.assign_ptr(real_buf, static_cast<int64_t>(real_tot_length));
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        if (OB_SUCC(ret) && OB_FAIL(to_strings.push_back(tmp_string))) {
 | 
			
		||||
          LOG_WARN("failed to push back string", K(ret));
 | 
			
		||||
 | 
			
		||||
@ -107,7 +107,7 @@ int ObParser::split_multiple_stmt(
 | 
			
		||||
      ObString part(str_len, stmt.ptr() + offset);
 | 
			
		||||
      ObString remain_part(remain, stmt.ptr() + offset);
 | 
			
		||||
      //first try parse part str, because it's have less length and need less memory
 | 
			
		||||
      if (OB_FAIL(tmp_ret = parse(part, parse_result, parse_mode))) {
 | 
			
		||||
      if (OB_FAIL(tmp_ret = parse(part, parse_result, parse_mode, false, true))) {
 | 
			
		||||
        //if parser part str failed, then try parse all remain part, avoid parse many times:
 | 
			
		||||
        //bug: https://work.aone.alibaba-inc.com/issue/34642901
 | 
			
		||||
        tmp_ret = OB_SUCCESS;
 | 
			
		||||
@ -146,12 +146,14 @@ int ObParser::split_multiple_stmt(
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObParser::parse_sql(const ObString& stmt, ParseResult& parse_result)
 | 
			
		||||
int ObParser::parse_sql(const ObString& stmt, ParseResult& parse_result, const bool no_throw_parser_error)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  ObSQLParser sql_parser(*(ObIAllocator*)(parse_result.malloc_pool_), sql_mode_);
 | 
			
		||||
  if (OB_FAIL(sql_parser.parse(stmt.ptr(), stmt.length(), parse_result))) {
 | 
			
		||||
    LOG_INFO("failed to parse stmt as sql", K(stmt), K(ret));
 | 
			
		||||
    if (!no_throw_parser_error) {
 | 
			
		||||
      LOG_INFO("failed to parse stmt as sql", K(stmt), K(ret));
 | 
			
		||||
    }
 | 
			
		||||
  } else if (parse_result.is_dynamic_sql_) {
 | 
			
		||||
    memmove(parse_result.no_param_sql_ + parse_result.no_param_sql_len_,
 | 
			
		||||
        parse_result.input_sql_ + parse_result.pl_parse_info_.last_pl_symbol_pos_,
 | 
			
		||||
@ -160,11 +162,11 @@ int ObParser::parse_sql(const ObString& stmt, ParseResult& parse_result)
 | 
			
		||||
  } else { /*do nothing*/
 | 
			
		||||
  }
 | 
			
		||||
  if (parse_result.is_fp_ || parse_result.is_multi_query_) {
 | 
			
		||||
    if (OB_FAIL(ret)) {
 | 
			
		||||
    if (OB_FAIL(ret) && !no_throw_parser_error) {
 | 
			
		||||
      LOG_WARN("failed to fast parameterize", K(stmt), K(ret));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if (OB_FAIL(ret)) {
 | 
			
		||||
  if (OB_FAIL(ret) && !no_throw_parser_error) {
 | 
			
		||||
    auto err_charge_sql_mode = lib::is_oracle_mode();
 | 
			
		||||
    LOG_WARN("failed to parse the statement",
 | 
			
		||||
        K(stmt),
 | 
			
		||||
@ -206,7 +208,8 @@ int ObParser::parse_sql(const ObString& stmt, ParseResult& parse_result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObParser::parse(
 | 
			
		||||
    const ObString& query, ParseResult& parse_result, ParseMode parse_mode, const bool is_batched_multi_stmt_split_on)
 | 
			
		||||
    const ObString& query, ParseResult& parse_result, ParseMode parse_mode, const bool is_batched_multi_stmt_split_on,
 | 
			
		||||
    const bool no_throw_parser_error)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
 | 
			
		||||
@ -268,8 +271,10 @@ int ObParser::parse(
 | 
			
		||||
    LOG_DEBUG("check parse_result param", "connection charset", ObCharset::charset_name(connection_collation_));
 | 
			
		||||
  }
 | 
			
		||||
  if (OB_SUCC(ret)) {
 | 
			
		||||
    if (OB_FAIL(parse_sql(stmt, parse_result))) {
 | 
			
		||||
      LOG_WARN("failed to parse stmt as sql", K(stmt), K(parse_mode), K(ret));
 | 
			
		||||
    if (OB_FAIL(parse_sql(stmt, parse_result, no_throw_parser_error))) {
 | 
			
		||||
      if (!no_throw_parser_error) {
 | 
			
		||||
        LOG_WARN("failed to parse stmt as sql", K(stmt), K(parse_mode), K(ret));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
 | 
			
		||||
@ -53,10 +53,18 @@ public:
 | 
			
		||||
  bool is_single_stmt(const common::ObString& stmt);
 | 
			
		||||
  int split_multiple_stmt(const common::ObString& stmt, common::ObIArray<common::ObString>& queries,
 | 
			
		||||
      ObMPParseStat& parse_fail, bool is_ret_first_stmt = false);
 | 
			
		||||
  int parse_sql(const common::ObString& stmt, ParseResult& parse_result);
 | 
			
		||||
  //@param:
 | 
			
		||||
  //  no_throw_parser_error is used to mark not throw parser error. in the split multi stmt
 | 
			
		||||
  //  situation we will try find ';' delimiter to parser part of string in case of save memory,
 | 
			
		||||
  //  but this maybe parser error and throw error info. However, we will still try parser remain
 | 
			
		||||
  //  string when parse part of string failed, if we throw parse part error info, maybe will let
 | 
			
		||||
  //  someone misunderstand have bug, So, we introduce this mark to decide to throw parser erorr.
 | 
			
		||||
  //  eg: select '123;' from dual; select '123' from dual;
 | 
			
		||||
  int parse_sql(const common::ObString& stmt, ParseResult& parse_result,
 | 
			
		||||
      const bool no_throw_parser_error = false);
 | 
			
		||||
 | 
			
		||||
  virtual int parse(const common::ObString& stmt, ParseResult& parse_result, ParseMode mode = STD_MODE,
 | 
			
		||||
      const bool is_batched_multi_stmt_split_on = false);
 | 
			
		||||
      const bool is_batched_multi_stmt_split_on = false, const bool no_throw_parser_error = false);
 | 
			
		||||
 | 
			
		||||
  virtual void free_result(ParseResult& parse_result);
 | 
			
		||||
  /**
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user