提交 ce63c892 编写于 作者: O obdev 提交者: wangzelin.wzl

fix bug of tinytext type in mysql mode can insert 256 bytes chars

上级 1ec7b00f
......@@ -2348,7 +2348,8 @@ int ObDDLOperator::alter_table_column(const ObTableSchema& origin_table_schema,
new_table_schema.get_charset_type(),
new_table_schema.get_collation_type()))) {
RS_LOG(WARN, "failed to fill column charset info");
} else if (OB_FAIL(ObDDLResolver::check_text_column_length_and_promote(*alter_column_schema))) {
} else if (OB_FAIL(ObDDLResolver::check_text_column_length_and_promote(*alter_column_schema,
origin_table_schema.get_table_id()))) {
RS_LOG(WARN, "failed to check text or blob column length");
}
} else if (ObEnumSetTC == col_tc) {
......@@ -2568,7 +2569,8 @@ int ObDDLOperator::alter_table_column(const ObTableSchema& origin_table_schema,
new_table_schema.get_charset_type(),
new_table_schema.get_collation_type()))) {
RS_LOG(WARN, "failed to fill column charset info");
} else if (OB_FAIL(ObDDLResolver::check_text_column_length_and_promote(*alter_column_schema))) {
} else if (OB_FAIL(ObDDLResolver::check_text_column_length_and_promote(*alter_column_schema,
origin_table_schema.get_table_id()))) {
RS_LOG(WARN, "failed to check text or blob column length");
}
}
......@@ -2775,7 +2777,8 @@ int ObDDLOperator::alter_table_column(const ObTableSchema& origin_table_schema,
new_table_schema.get_charset_type(),
new_table_schema.get_collation_type()))) {
RS_LOG(WARN, "failed to fill column charset info");
} else if (OB_FAIL(ObDDLResolver::check_text_column_length_and_promote(*alter_column_schema))) {
} else if (OB_FAIL(ObDDLResolver::check_text_column_length_and_promote(*alter_column_schema,
origin_table_schema.get_table_id()))) {
RS_LOG(WARN, "failed to check text or blob column length");
}
}
......
......@@ -554,6 +554,11 @@ int ObCreateTableResolver::resolve(const ParseNode& parse_tree)
// do nothing
}
// 1、 resolve table_id first for check whether is inner_table
if (OB_SUCC(ret) && OB_FAIL(resolve_table_id_pre(create_table_node->children_[4]))) {
SQL_RESV_LOG(WARN, "resolve_table_id_pre failed", K(ret));
}
// consider index can be defined before column, so column should be
// resolved firstly;avoid to rescan table_element_list_node, use a
// array named index_node_position_list to record the position of indexes
......@@ -1576,7 +1581,7 @@ int ObCreateTableResolver::resolve_table_elements_from_select(const ParseNode& p
} else if (is_oracle_mode() && create_table_column_count > 0) {
if (column.is_string_type()) {
if (column.get_meta_type().is_lob()) {
if (OB_FAIL(check_text_column_length_and_promote(column))) {
if (OB_FAIL(check_text_column_length_and_promote(column, table_id_))) {
LOG_WARN("fail to check text or blob column length", K(ret), K(column));
}
} else if (OB_FAIL(check_string_column_length(column, share::is_oracle_mode()))) {
......@@ -1619,7 +1624,7 @@ int ObCreateTableResolver::resolve_table_elements_from_select(const ParseNode& p
} else {
if (column.is_string_type()) {
if (column.get_meta_type().is_lob()) {
if (OB_FAIL(check_text_column_length_and_promote(column))) {
if (OB_FAIL(check_text_column_length_and_promote(column, table_id_))) {
LOG_WARN("fail to check text or blob column length", K(ret), K(column));
}
} else if (OB_FAIL(check_string_column_length(column, share::is_oracle_mode()))) {
......
......@@ -513,6 +513,38 @@ int ObDDLResolver::set_database_name(const ObString& database_name)
return ret;
}
int ObDDLResolver::resolve_table_id_pre(ParseNode *node)
{
int ret = OB_SUCCESS;
if (NULL != node) {
ParseNode *option_node = NULL;
int32_t num = 0;
if(T_TABLE_OPTION_LIST != node->type_ || node->num_child_ < 1) {
ret = OB_ERR_UNEXPECTED;
SQL_RESV_LOG(WARN, "invalid parse node", K(ret));
} else if (OB_ISNULL(node->children_) || OB_ISNULL(session_info_)) {
ret = OB_ERR_UNEXPECTED;
SQL_RESV_LOG(WARN, "node children or session_info_ is null", K(node->children_), K(session_info_), K(ret));
} else {
num = node->num_child_;
}
for (int64_t i = 0; OB_SUCC(ret) && i < num; ++i) {
if (OB_ISNULL(option_node = node->children_[i])) {
ret = OB_ERR_UNEXPECTED;
SQL_RESV_LOG(WARN, "node is null", K(ret));
} else if (option_node->type_ == T_TABLE_ID) {
if (OB_ISNULL(option_node->children_[0])) {
ret = OB_ERR_UNEXPECTED;
SQL_RESV_LOG(WARN, "option_node child is null", K(option_node->children_[0]), K(ret));
} else {
table_id_ = static_cast<uint64_t>(option_node->children_[0]->value_);
}
}
}
}
return ret;
}
int ObDDLResolver::resolve_table_options(ParseNode* node, bool is_index_option)
{
int ret = OB_SUCCESS;
......@@ -1875,7 +1907,7 @@ int ObDDLResolver::resolve_column_definition(ObColumnSchemaV2& column, ParseNode
if (OB_FAIL(check_and_fill_column_charset_info(column, charset_type_, collation_type_))) {
SQL_RESV_LOG(WARN, "fail to check and fill column charset info", K(ret));
} else if (data_type.get_meta_type().is_lob()) {
if (OB_FAIL(check_text_column_length_and_promote(column))) {
if (OB_FAIL(check_text_column_length_and_promote(column, table_id_))) {
SQL_RESV_LOG(WARN, "fail to check text or blob column length", K(ret), K(column));
}
} else if (OB_FAIL(check_string_column_length(column, lib::is_oracle_mode()))) {
......@@ -2913,8 +2945,12 @@ int ObDDLResolver::check_urowid_column_length(const share::schema::ObColumnSchem
return ret;
}
int ObDDLResolver::check_text_length(
ObCharsetType cs_type, ObCollationType co_type, const char* name, ObObjType& type, int32_t& length)
int ObDDLResolver::check_text_length(ObCharsetType cs_type,
ObCollationType co_type,
const char* name,
ObObjType& type,
int32_t& length,
bool need_rewrite_length)
{
int ret = OB_SUCCESS;
int64_t mbmaxlen = 0;
......@@ -2961,17 +2997,50 @@ int ObDDLResolver::check_text_length(
length = default_length;
}
}
if (OB_SUCC(ret) && share::is_mysql_mode() && need_rewrite_length) {
if (OB_FAIL(rewrite_text_length_mysql(type, length))) {
LOG_WARN("check_text_length_mysql fails", K(ret), K(type), K(length));
}
}
return ret;
}
// old version ObTinyTextType, ObTextType, ObMediumTextType, ObLongTextType max_length is incorrect
// correct max_legth is ObTinyTextType:255 etc.
// so when create new user table, must rewrite max column length
int ObDDLResolver::rewrite_text_length_mysql(ObObjType &type, int32_t &length)
{
int ret = OB_SUCCESS;
int32_t max_length = ObAccuracy::MAX_ACCURACY[type].get_length();
if (length < 0 || length > max_length) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("length can not be less than 0 or larger than max_length",
K(ret), K(type), K(length), K(max_length));
} else if (ob_is_text_tc(type) && max_length == length) {
length = length - 1;
}
return ret;
}
// TODO texttc should care about the the defined length not the actual length
int ObDDLResolver::check_text_column_length_and_promote(ObColumnSchemaV2& column)
int ObDDLResolver::check_text_column_length_and_promote(ObColumnSchemaV2& column, int64_t table_id)
{
int ret = OB_SUCCESS;
bool need_check_length = true;
ObObjType type = column.get_data_type();
int32_t length = column.get_data_length();
if (OB_FAIL(check_text_length(
column.get_charset_type(), column.get_collation_type(), column.get_column_name(), type, length))) {
if (OB_INVALID_ID != table_id && is_inner_table(table_id)) {
// inner table don't need to rewrite
// if table_id == OB_INVALID_ID, this is not inner_table
need_check_length = false;
}
if (OB_FAIL(check_text_length(column.get_charset_type(),
column.get_collation_type(),
column.get_column_name(),
type,
length,
need_check_length))) {
LOG_WARN("failed to check text length", K(ret), K(column));
} else {
column.set_data_type(type);
......
......@@ -142,8 +142,14 @@ public:
static const int64_t DEFAULT_TABLE_DOP = 1;
explicit ObDDLResolver(ObResolverParams& params);
virtual ~ObDDLResolver();
static int check_text_length(
ObCharsetType cs_type, ObCollationType co_type, const char* name, ObObjType& type, int32_t& length);
static int check_text_length(ObCharsetType cs_type,
ObCollationType co_type,
const char* name,
ObObjType& type,
int32_t& length,
bool need_rewrite_length);
static int rewrite_text_length_mysql(ObObjType &type, int32_t &length);
static int check_uniq_allow(
share::schema::ObTableSchema& table_schema, obrpc::ObCreateIndexArg& index_arg, bool& allow);
static int get_primary_key_default_value(common::ObObjType type, common::ObObj& default_value);
......@@ -181,7 +187,7 @@ public:
static int cast_enum_or_set_default_value(
const share::schema::ObColumnSchemaV2& column, common::ObObjCastParams& params, common::ObObj& def_val);
int check_partition_name_duplicate(ParseNode* node, bool is_oracle_modle = false);
static int check_text_column_length_and_promote(share::schema::ObColumnSchemaV2& column);
static int check_text_column_length_and_promote(share::schema::ObColumnSchemaV2& column, int64_t table_id);
static int get_enable_split_partition(const int64_t tenant_id, bool& enable_split_partition);
typedef common::hash::ObPlacementHashSet<share::schema::ObIndexNameHashWrapper, common::OB_MAX_COLUMN_NUMBER>
IndexNameSet;
......@@ -250,6 +256,7 @@ protected:
int set_table_name(const common::ObString& table_name);
int set_database_name(const common::ObString& database_name);
int set_encryption_name(const common::ObString& encryption);
int resolve_table_id_pre(ParseNode *node);
int resolve_table_options(ParseNode* node, bool is_index_option);
int resolve_table_option(const ParseNode* node, const bool is_index_option);
int resolve_column_definition_ref(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册