提交 db82de6a 编写于 作者: M Monk-Liu 提交者: LINGuanRen

[cp]: fix 4 bugs for NO_BACKSLASH_ESCAPES mode.

上级 e28151b1
......@@ -952,7 +952,7 @@ inline int obj_print_plain_str<ObHexStringType>(
ret = obj_print_sql<ObHexStringType>(obj, buffer, length, pos, params); \
} else if (OB_FAIL(databuff_printf(buffer, length, pos, "'"))) { \
} else if (src_type == dst_type || src_type == CHARSET_INVALID) { \
ObHexEscapeSqlStr sql_str(obj.get_string()); \
ObHexEscapeSqlStr sql_str(obj.get_string(), params.skip_escape_); \
pos += sql_str.to_string(buffer + pos, length - pos); \
ret = databuff_printf(buffer, length, pos, "'"); \
} else { \
......@@ -965,7 +965,7 @@ inline int obj_print_plain_str<ObHexStringType>(
length - pos, \
result_len))) { \
} else { \
ObHexEscapeSqlStr sql_str(ObString(result_len, buffer + pos)); \
ObHexEscapeSqlStr sql_str(ObString(result_len, buffer + pos), params.skip_escape_); \
int64_t temp_pos = pos + result_len; \
int64_t data_len = sql_str.to_string(buffer + temp_pos, length - temp_pos); \
if (OB_UNLIKELY(temp_pos + data_len >= length)) { \
......@@ -2125,7 +2125,7 @@ inline uint64_t obj_crc64_v3<ObIntervalDSType>(const ObObj& obj, const uint64_t
int ret = OB_SUCCESS; \
if (OB_FAIL(databuff_printf(buffer, length, pos, "n'"))) { \
} else if (src_type == dst_type) { \
ObHexEscapeSqlStr sql_str(obj.get_string()); \
ObHexEscapeSqlStr sql_str(obj.get_string(), params.skip_escape_); \
pos += sql_str.to_string(buffer + pos, length - pos); \
ret = databuff_printf(buffer, length, pos, "'"); \
} else { \
......@@ -2138,7 +2138,7 @@ inline uint64_t obj_crc64_v3<ObIntervalDSType>(const ObObj& obj, const uint64_t
length - pos, \
result_len))) { \
} else { \
ObHexEscapeSqlStr sql_str(ObString(result_len, buffer + pos)); \
ObHexEscapeSqlStr sql_str(ObString(result_len, buffer + pos), params.skip_escape_); \
int64_t temp_pos = pos + result_len; \
int64_t data_len = sql_str.to_string(buffer + temp_pos, length - temp_pos); \
if (OB_UNLIKELY(temp_pos + data_len >= length)) { \
......
......@@ -1395,6 +1395,11 @@ DEF_TO_STRING(ObHexEscapeSqlStr)
buf[buf_pos++] = *cur;
}
}
} else if (skip_escape_) {
// do not escape_ while in NO_BACKSLASH_ESCAPES mode
for (const char *cur = str_.ptr(); cur < end && buf_pos < buf_len; ++cur) {
buf[buf_pos++] = *cur;
}
} else {
for (const char* cur = str_.ptr(); cur < end && buf_pos < buf_len; ++cur) {
switch (*cur) {
......
......@@ -1049,7 +1049,9 @@ struct ObObjPrintParams {
struct {
uint32_t need_cast_expr_ : 1;
uint32_t is_show_create_view_ : 1;
uint32_t reserved_ : 30;
uint32_t use_memcpy_ : 1;
uint32_t skip_escape_ : 1;
uint32_t reserved_ : 28;
};
};
};
......@@ -4125,7 +4127,9 @@ public:
class ObHexEscapeSqlStr {
public:
ObHexEscapeSqlStr(const common::ObString& str) : str_(str)
ObHexEscapeSqlStr(const common::ObString &str) : str_(str), skip_escape_(false)
{}
ObHexEscapeSqlStr(const common::ObString &str, const bool skip_escape) : str_(str), skip_escape_(skip_escape)
{}
ObString str() const
{
......@@ -4136,6 +4140,7 @@ public:
private:
ObString str_;
bool skip_escape_;
};
} // namespace common
......
......@@ -42,7 +42,7 @@ extern "C" {
#define SMO_MYSQL40 (1ULL << 17) /*not support*/
#define SMO_ANSI (1ULL << 18)
#define SMO_NO_AUTO_VALUE_ON_ZERO (1ULL << 19) /* support */
#define SMO_NO_BACKSLASH_ESCAPES (1ULL << 20) /* not support now */
#define SMO_NO_BACKSLASH_ESCAPES (1ULL << 20) /* support */
#define SMO_STRICT_TRANS_TABLES (1ULL << 21) /* support */
#define SMO_STRICT_ALL_TABLES (1ULL << 22) /* support */
#define SMO_NO_ZERO_IN_DATE (1ULL << 23) /* deprecated as of MySQL 5.6.17 */
......
......@@ -405,7 +405,8 @@ protected:
rowkey_dist_ctx_(NULL),
iter_end_(false),
saved_session_(NULL)
{}
{
}
virtual ~ObTableModifyCtx()
{
destroy();
......@@ -439,7 +440,14 @@ protected:
}
const ObObjPrintParams get_obj_print_params()
{
return CREATE_OBJ_PRINT_PARAM(exec_ctx_.get_my_session());
ObObjPrintParams print_params = CREATE_OBJ_PRINT_PARAM(exec_ctx_.get_my_session());
print_params.need_cast_expr_ = true;
// bugfix:https://work.aone.alibaba-inc.com/issue/36658497
// in NO_BACKSLASH_ESCAPES, obj_print_sql<ObVarcharType> won't escape.
// We use skip_escape_ to indicate this case. It will finally be passed to ObHexEscapeSqlStr.
GET_SQL_MODE_BIT(
IS_NO_BACKSLASH_ESCAPES, exec_ctx_.get_my_session()->get_sql_mode(), print_params.skip_escape_);
return print_params;
}
int check_stack();
......
......@@ -403,7 +403,8 @@ ObTableModifyOp::ObTableModifyOp(ObExecContext& ctx, const ObOpSpec& spec, ObOpI
iter_end_(false),
saved_session_(NULL),
fk_self_ref_row_res_infos_()
{}
{
}
int ObTableModifyOp::inner_open()
{
......
......@@ -326,7 +326,13 @@ public:
}
const ObObjPrintParams get_obj_print_params()
{
return CREATE_OBJ_PRINT_PARAM(ctx_.get_my_session());
ObObjPrintParams print_params = CREATE_OBJ_PRINT_PARAM(ctx_.get_my_session());
print_params.need_cast_expr_ = true;
// bugfix:https://work.aone.alibaba-inc.com/issue/36658497
// in NO_BACKSLASH_ESCAPES, obj_print_sql<ObVarcharType> won't escape.
// We use skip_escape_ to indicate this case. It will finally be passed to ObHexEscapeSqlStr.
GET_SQL_MODE_BIT(IS_NO_BACKSLASH_ESCAPES, ctx_.get_my_session()->get_sql_mode(), print_params.skip_escape_);
return print_params;
}
int init_foreign_key_operation();
int check_rowkey_is_null(const ObExprPtrIArray& row, int64_t rowkey_cnt, bool& is_null) const;
......
......@@ -274,7 +274,13 @@ int ObLoadDataResolver::resolve(const ParseNode& parse_tree)
if (OB_SUCC(ret)) {
/* 5. opt_field */
ObDataInFileStruct& data_struct_in_file = load_stmt->get_data_struct_in_file();
const ParseNode* child_node = node->children_[ENUM_OPT_FIELD];
bool no_default_escape = false;
IS_NO_BACKSLASH_ESCAPES(session_info_->get_sql_mode(), no_default_escape);
if (no_default_escape) {
data_struct_in_file.field_escaped_char_ = INT64_MAX;
data_struct_in_file.field_escaped_str_ = "";
}
const ParseNode *child_node = node->children_[ENUM_OPT_FIELD];
if (NULL != child_node) {
if (T_INTO_FIELD_LIST != child_node->type_) {
ret = OB_ERR_UNEXPECTED;
......
......@@ -2275,11 +2275,25 @@ int ObRawExprResolverImpl::process_like_node(const ParseNode* node, ObRawExpr*&
escape_node.str_value_ = "\\";
escape_node.text_len_ = 0;
escape_node.raw_text_ = NULL;
/*
bugfix:https://work.aone.alibaba-inc.com/issue/36691548
in NO_BACKSLASH_ESCAPES mode, 'like BINARY xxx' stmt should also set the escapes as null, instead of '\'
*/
bool no_escapes = false;
if (node->children_[1]->type_ == T_FUN_SYS && node->children_[1]->num_child_ == 2 &&
node->children_[1]->children_[0]->str_len_ == 4 &&
(0 == strcmp(node->children_[1]->children_[0]->str_value_, "cast")) &&
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);
}
if (OB_FAIL(process_datatype_or_questionmark(escape_node, escape_expr))) {
LOG_WARN("fail to resolver defalut excape node", K(ret));
} else if (OB_FAIL(t_expr->add_param_expr(escape_expr))) {
LOG_WARN("fail to set param expr");
} else if (lib::is_oracle_mode()) {
} else if (lib::is_oracle_mode() || no_escapes) {
// Oracle mode, if not specify escape, then no escape, but the implementation of like must contain escape
// so we rewrite like without escape
// c1 like '%x\x%' --> c1 like replace('%x\x%', '\','\\') escape '\' -> c1 like '%x\\x%' escape '\'
......
......@@ -89,6 +89,18 @@ struct ObSessionNLSParams // oracle nls parameters
#define CREATE_OBJ_PRINT_PARAM(session) (NULL != (session) ? (session)->create_obj_print_params() : ObObjPrintParams())
// flag is a single bit, but marco(e.g., IS_NO_BACKSLASH_ESCAPES) compare two 64-bits int using '&';
// if we directly assign the result to flag(single bit), only the last bit of the result is used,
// which is equal to 'flag = result & 1;'.
// So we first convert the result to bool(tmp_flag) and assign the bool to flag, which is equal to
// 'flag = result!=0;'.
#define GET_SQL_MODE_BIT(marco, sql_mode, flag) \
do { \
bool tmp_flag = false; \
marco(sql_mode, tmp_flag); \
flag = tmp_flag; \
} while (0)
#ifndef NDEBUG
#define CHECK_COMPATIBILITY_MODE(session) \
do { \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册