diff --git a/src/sql/ob_sql_utils.cpp b/src/sql/ob_sql_utils.cpp index 6e9de1a027e38ee52a9bd9887920be48a4ed67c5..656a330c6454bbfc8e7af56c231053f0f494e6e0 100644 --- a/src/sql/ob_sql_utils.cpp +++ b/src/sql/ob_sql_utils.cpp @@ -1204,7 +1204,10 @@ int ObSQLUtils::check_and_convert_table_name(const ObCollationType cs_type, cons const char* name_str = name.ptr(); const int64_t max_user_table_name_length = share::is_oracle_mode() ? OB_MAX_USER_TABLE_NAME_LENGTH_ORACLE : OB_MAX_USER_TABLE_NAME_LENGTH_MYSQL; - if (0 == name_len || name_len > (max_user_table_name_length * OB_MAX_CHAR_LEN) || OB_ISNULL(name_str)) { + const int64_t max_index_name_prefix_len = 30; + if (0 == name_len || (!is_index_table && (name_len > (max_user_table_name_length * OB_MAX_CHAR_LEN))) || + (is_index_table && (name_len > (max_user_table_name_length * OB_MAX_CHAR_LEN + max_index_name_prefix_len))) || + OB_ISNULL(name_str)) { ret = OB_WRONG_TABLE_NAME; LOG_USER_ERROR(OB_WRONG_TABLE_NAME, static_cast(name_len), name_str); LOG_WARN("incorrect table name", K(name), K(ret)); @@ -1279,14 +1282,21 @@ int ObSQLUtils::check_column_name(const ObCollationType cs_type, ObString& name) bool last_char_is_space = false; const char* end = name.ptr() + name.length(); const char* name_str = name.ptr(); - size_t name_char_len = 0; + size_t name_len = 0; // char semantics for MySQL mode, and byte semantics for Oracle mode + size_t byte_length = 0; + int is_mb_char = 0; while (OB_SUCCESS == ret && name_str != end) { last_char_is_space = ObCharset::is_space(CS_TYPE_UTF8MB4_GENERAL_CI, *name_str); if (ObCharset::usemb(CS_TYPE_UTF8MB4_GENERAL_CI)) { - int char_len = ObCharset::is_mbchar(CS_TYPE_UTF8MB4_GENERAL_CI, name_str, end); - if (char_len) { - name_str += char_len; - name_char_len++; + is_mb_char = ObCharset::is_mbchar(CS_TYPE_UTF8MB4_GENERAL_CI, name_str, end); + if (is_mb_char) { + byte_length = ObCharset::charpos(CS_TYPE_UTF8MB4_GENERAL_CI, name_str, end - name_str, 1); + name_str += byte_length; + if (share::is_mysql_mode()) { + name_len++; + } else { + name_len += byte_length; + } continue; } } @@ -1295,7 +1305,7 @@ int ObSQLUtils::check_column_name(const ObCollationType cs_type, ObString& name) ret = OB_WRONG_COLUMN_NAME; } else { name_str++; - name_char_len++; + name_len++; } } @@ -1304,10 +1314,10 @@ int ObSQLUtils::check_column_name(const ObCollationType cs_type, ObString& name) ret = OB_WRONG_COLUMN_NAME; LOG_USER_ERROR(OB_WRONG_COLUMN_NAME, name.length(), name.ptr()); LOG_WARN("incorrect column name", K(name), K(ret)); - } else if (name_char_len > static_cast(OB_MAX_COLUMN_NAME_LENGTH)) { + } else if (name_len > static_cast(OB_MAX_COLUMN_NAME_LENGTH)) { ret = OB_ERR_TOO_LONG_IDENT; LOG_USER_ERROR(OB_ERR_TOO_LONG_IDENT, name.length(), name.ptr()); - LOG_WARN("column name is too long", K(name), K(ret)); + LOG_WARN("column name is too long", K(ret), K(name), K(name_len)); } } return ret; @@ -1345,33 +1355,39 @@ int ObSQLUtils::check_ident_name( bool last_char_is_space = false; const char* end = name.ptr() + name.length(); const char* name_str = name.ptr(); - size_t name_char_len = 0; + size_t name_len = 0; // char semantics for MySQL mode, and byte semantics for Oracle mode + size_t byte_length = 0; + int is_mb_char = 0; while (OB_SUCCESS == ret && NULL != name_str && name_str != end) { last_char_is_space = ObCharset::is_space(CS_TYPE_UTF8MB4_GENERAL_CI, *name_str); if (ObCharset::usemb(CS_TYPE_UTF8MB4_GENERAL_CI)) { - int char_len = ObCharset::is_mbchar(CS_TYPE_UTF8MB4_GENERAL_CI, name_str, end); - if (char_len) { - name_str += char_len; - name_char_len++; + is_mb_char = ObCharset::is_mbchar(CS_TYPE_UTF8MB4_GENERAL_CI, name_str, end); + if (is_mb_char) { + byte_length = ObCharset::charpos(CS_TYPE_UTF8MB4_GENERAL_CI, name_str, end - name_str, 1); + name_str += byte_length; + if (share::is_mysql_mode()) { + name_len++; + } else { + name_len += byte_length; + } continue; } } - if (check_for_path_char && ('/' == *name_str || '\\' == *name_str || '~' == *name_str || '.' == *name_str)) { ret = OB_ERR_WRONG_IDENT_NAME; LOG_WARN("Incorrect database name", K(name), K(ret)); } else { name_str++; - name_char_len++; + name_len++; } } if (OB_SUCC(ret)) { if (last_char_is_space) { ret = OB_ERR_WRONG_IDENT_NAME; LOG_WARN("incorrect ident name", K(name), K(ret)); - } else if (name_char_len > static_cast(max_ident_len)) { + } else if (name_len > static_cast(max_ident_len)) { ret = OB_ERR_TOO_LONG_IDENT; - LOG_WARN("ident name is too long", K(name), K(ret)); + LOG_WARN("ident name is too long", K(ret), K(name), K(name.length()), K(name_len)); } } return ret; diff --git a/src/sql/resolver/ddl/ob_create_table_resolver.cpp b/src/sql/resolver/ddl/ob_create_table_resolver.cpp index 14c0ea8cd40ccfbaebd012e1d6935af6be670c2b..8c64302a3901edb79002159ffd4ced8ad41e736c 100644 --- a/src/sql/resolver/ddl/ob_create_table_resolver.cpp +++ b/src/sql/resolver/ddl/ob_create_table_resolver.cpp @@ -946,9 +946,6 @@ int ObCreateTableResolver::check_column_name_duplicate(const ParseNode* node) if (OB_ISNULL(name_node)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("name node can not be null", K(ret)); - } else if (name_node->str_len_ > OB_MAX_COLUMN_NAME_LENGTH) { - ret = OB_ERR_TOO_LONG_IDENT; - LOG_USER_ERROR(OB_ERR_TOO_LONG_IDENT, (int)name_node->str_len_, name_node->str_value_); } else if (0 == name_node->str_len_) { ret = OB_WRONG_COLUMN_NAME; LOG_USER_ERROR(OB_WRONG_COLUMN_NAME, (int)name_node->str_len_, name_node->str_value_); @@ -2461,11 +2458,14 @@ int ObCreateTableResolver::resolve_index_name( } if (OB_SUCC(ret)) { - const int64_t max_user_table_name_length = - share::is_oracle_mode() ? OB_MAX_USER_TABLE_NAME_LENGTH_ORACLE : OB_MAX_USER_TABLE_NAME_LENGTH_MYSQL; - if (index_name_.length() > max_user_table_name_length) { - ret = OB_ERR_TOO_LONG_IDENT; - LOG_USER_ERROR(OB_ERR_TOO_LONG_IDENT, index_name_.length(), index_name_.ptr()); + ObCollationType cs_type = CS_TYPE_INVALID; + if (OB_UNLIKELY(NULL == session_info_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("session if NULL", K(ret)); + } else if (OB_FAIL(session_info_->get_collation_connection(cs_type))) { + LOG_WARN("fail to get collation connection", K(ret)); + } else if (OB_FAIL(ObSQLUtils::check_index_name(cs_type, index_name_))) { + LOG_WARN("fail to check index name", K(ret), K(index_name_)); } } diff --git a/src/sql/resolver/ddl/ob_create_view_resolver.cpp b/src/sql/resolver/ddl/ob_create_view_resolver.cpp index 6bcf39396363c407291717ad7ed059ca3cd82b1a..3381055931ee3bfe85e5fdfe560ee2bcf3318ca1 100644 --- a/src/sql/resolver/ddl/ob_create_view_resolver.cpp +++ b/src/sql/resolver/ddl/ob_create_view_resolver.cpp @@ -117,11 +117,13 @@ int ObCreateViewResolver::resolve(const ParseNode& parse_tree) } if (OB_SUCC(ret)) { - const int64_t max_user_table_name_length = - share::is_oracle_mode() ? OB_MAX_USER_TABLE_NAME_LENGTH_ORACLE : OB_MAX_USER_TABLE_NAME_LENGTH_MYSQL; - if (view_name.length() > max_user_table_name_length) { - ret = OB_ERR_TOO_LONG_IDENT; - LOG_USER_ERROR(OB_ERR_TOO_LONG_IDENT, view_name.length(), view_name.ptr()); + ObNameCaseMode mode = OB_NAME_CASE_INVALID; + bool perserve_lettercase = false; + if (OB_FAIL(session_info_->get_name_case_mode(mode))) { + LOG_WARN("fail to get name case mode", K(ret), K(mode)); + } else if (FALSE_IT(perserve_lettercase = share::is_oracle_mode() ? true : (mode != OB_LOWERCASE_AND_INSENSITIVE))) { + } else if (OB_FAIL(ObSQLUtils::check_and_convert_table_name(CS_TYPE_UTF8MB4_GENERAL_CI, perserve_lettercase, view_name))) { + LOG_WARN("fail to check and convert view_name", K(ret), K(view_name)); } else { table_schema.set_tenant_id(session_info_->get_effective_tenant_id()); table_schema.set_tablegroup_id(combine_id(OB_SYS_TENANT_ID, OB_SYS_TABLEGROUP_ID)); @@ -304,8 +306,6 @@ int ObCreateViewResolver::resolve(const ParseNode& parse_tree) // do nothing } } - - // 检查 mysql 模式下列名定义 if (share::is_mysql_mode() && !(is_sync_ddl_user && session_info_->is_inner())) { if (OB_FAIL(ret)) { // do nothing diff --git a/src/sql/resolver/ddl/ob_ddl_resolver.cpp b/src/sql/resolver/ddl/ob_ddl_resolver.cpp index 1b5d16f2410112026747e4e513a9d4efb42e2561..f8b70d437c805d4e43360a8d0a67eed828458f9c 100644 --- a/src/sql/resolver/ddl/ob_ddl_resolver.cpp +++ b/src/sql/resolver/ddl/ob_ddl_resolver.cpp @@ -1799,7 +1799,7 @@ int ObDDLResolver::resolve_column_name(common::ObString& col_name, ParseNode* no col_name.assign_ptr(node->str_value_, node->str_len_); int32_t name_length = col_name.length(); const char* name_ptr = col_name.ptr(); - if (name_length > OB_MAX_COLUMN_NAME_LENGTH) { + if (name_length > OB_MAX_COLUMN_NAME_LENGTH * OB_MAX_CHAR_LEN) { ret = OB_ERR_TOO_LONG_IDENT; _SQL_RESV_LOG( WARN, "identifier name '%.*s' is too long, ret=%d", static_cast(name_length), name_ptr, ret); diff --git a/src/sql/session/ob_basic_session_info.cpp b/src/sql/session/ob_basic_session_info.cpp index 6244029fcc80c7908d957496586f8309f2097055..b0a580cc7d62a8f9e9a5f056dd9a0e2aa45cfa24 100644 --- a/src/sql/session/ob_basic_session_info.cpp +++ b/src/sql/session/ob_basic_session_info.cpp @@ -641,7 +641,7 @@ int ObBasicSessionInfo::set_default_database( const ObString& database_name, const ObCollationType coll_type /*= CS_TYPE_INVALID */) { int ret = OB_SUCCESS; - if (database_name.length() > OB_MAX_DATABASE_NAME_LENGTH) { + if (database_name.length() > OB_MAX_DATABASE_NAME_LENGTH * OB_MAX_CHAR_LEN) { ret = OB_INVALID_ARGUMENT_FOR_LENGTH; LOG_WARN("invalid length for database_name", K(database_name), K(ret)); } else { diff --git a/src/sql/session/ob_basic_session_info.h b/src/sql/session/ob_basic_session_info.h index b1ba519343a31066184b185a04eacfe071b32232..de2341cc77f60927c0ae1a2be25f331279b2069e 100644 --- a/src/sql/session/ob_basic_session_info.h +++ b/src/sql/session/ob_basic_session_info.h @@ -1689,12 +1689,12 @@ protected: } ~MultiThreadData() {} - common::ObString user_name_; // current user name - common::ObString host_name_; // current user host name - common::ObString client_ip_; // current user real client host name - common::ObString user_at_host_name_; // current user@host, for current_user() - common::ObString user_at_client_ip_; // current user@clientip, for user() - char database_name_[common::OB_MAX_DATABASE_NAME_BUF_LENGTH]; // default database + common::ObString user_name_; // current user name + common::ObString host_name_; // current user host name + common::ObString client_ip_; // current user real client host name + common::ObString user_at_host_name_; // current user@host, for current_user() + common::ObString user_at_client_ip_; // current user@clientip, for user() + char database_name_[common::OB_MAX_DATABASE_NAME_BUF_LENGTH * OB_MAX_CHAR_LEN]; // default database common::ObAddr peer_addr_; common::ObAddr user_client_addr_; int64_t cur_query_buf_len_;