diff --git a/src/sql/engine/expr/ob_expr_concat.cpp b/src/sql/engine/expr/ob_expr_concat.cpp index d9b3202d86..b5687ea3c0 100644 --- a/src/sql/engine/expr/ob_expr_concat.cpp +++ b/src/sql/engine/expr/ob_expr_concat.cpp @@ -218,13 +218,23 @@ int ObExprConcat::calc_result_typeN(ObExprResType &type, OZ (aggregate_string_type_and_charset_oracle(*type_ctx.get_session(), params, type)); OZ (deduce_string_param_calc_type_and_charset(*type_ctx.get_session(), type, params)); } else { - type.set_varchar(); + bool has_text = false; + for (int64_t i = 0; !has_text && i < param_num; ++i) { + if (ObTinyTextType != types[i].get_type() && types[i].is_text()) { + has_text = true; + } + } + if (has_text) { + type.set_type(ObLongTextType); + } else { + type.set_varchar(); + } OZ (aggregate_charsets_for_string_result(type, types, param_num, type_ctx.get_coll_type())); for (int64_t i = 0; i < param_num; ++i) { - types[i].set_calc_type(ObVarcharType); + types[i].set_calc_type(type.get_type()); types[i].set_calc_collation_type(type.get_collation_type()); } } diff --git a/src/sql/resolver/cmd/ob_show_resolver.cpp b/src/sql/resolver/cmd/ob_show_resolver.cpp index ef929a3964..1cb1b4dec7 100644 --- a/src/sql/resolver/cmd/ob_show_resolver.cpp +++ b/src/sql/resolver/cmd/ob_show_resolver.cpp @@ -433,36 +433,20 @@ int ObShowResolver::resolve(const ParseNode &parse_tree) show_db_id, show_db_name))) { LOG_WARN("fail to resolve show database", K(ret), K(real_tenant_id)); - } else if (OB_FAIL(stmt_need_privs.need_privs_.init(2))) { - LOG_WARN("fail to init need privs array", K(ret)); - } else { - ObNeedPriv need_priv; - need_priv.priv_level_ = OB_PRIV_USER_LEVEL; - need_priv.priv_set_ = OB_PRIV_DB_ACC; - stmt_need_privs.need_privs_.push_back(need_priv); - - need_priv.priv_level_ = OB_PRIV_DB_LEVEL; - need_priv.priv_set_ = OB_PRIV_DB_ACC; - need_priv.db_ = show_db_name; - stmt_need_privs.need_privs_.push_back(need_priv); - - if (OB_FAIL(schema_checker_->check_priv_or(session_priv, stmt_need_privs))) { - if (OB_ERR_NO_DB_PRIVILEGE == ret) { - LOG_USER_ERROR(OB_ERR_NO_DB_PRIVILEGE, session_priv.user_name_.length(), session_priv.user_name_.ptr(), - session_priv.host_name_.length(),session_priv.host_name_.ptr(), - show_db_name.length(), show_db_name.ptr()); - } else { - LOG_WARN("fail to check priv", K(ret)); - } + } else if (OB_FAIL(schema_checker_->check_db_access(session_priv, show_db_name))) { + if (OB_ERR_NO_DB_PRIVILEGE == ret) { + LOG_USER_ERROR(OB_ERR_NO_DB_PRIVILEGE, session_priv.user_name_.length(), session_priv.user_name_.ptr(), + session_priv.host_name_.length(),session_priv.host_name_.ptr(), + show_db_name.length(), show_db_name.ptr()); } else { - if (NULL != parse_tree.children_[0]) { - GEN_SQL_STEP_1(ObShowSqlSet::SHOW_CREATE_DATABASE_EXISTS); - GEN_SQL_STEP_2(ObShowSqlSet::SHOW_CREATE_DATABASE_EXISTS, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_SHOW_CREATE_DATABASE_TNAME, show_db_id); - } else { - GEN_SQL_STEP_1(ObShowSqlSet::SHOW_CREATE_DATABASE); - GEN_SQL_STEP_2(ObShowSqlSet::SHOW_CREATE_DATABASE, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_SHOW_CREATE_DATABASE_TNAME, show_db_id); - } + LOG_WARN("fail to check priv", K(ret)); } + } else if (NULL != parse_tree.children_[0]) { + GEN_SQL_STEP_1(ObShowSqlSet::SHOW_CREATE_DATABASE_EXISTS); + GEN_SQL_STEP_2(ObShowSqlSet::SHOW_CREATE_DATABASE_EXISTS, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_SHOW_CREATE_DATABASE_TNAME, show_db_id); + } else { + GEN_SQL_STEP_1(ObShowSqlSet::SHOW_CREATE_DATABASE); + GEN_SQL_STEP_2(ObShowSqlSet::SHOW_CREATE_DATABASE, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_SHOW_CREATE_DATABASE_TNAME, show_db_id); } } }(); diff --git a/src/sql/resolver/dcl/ob_grant_resolver.cpp b/src/sql/resolver/dcl/ob_grant_resolver.cpp index 3ecab1134c..9425bb3995 100644 --- a/src/sql/resolver/dcl/ob_grant_resolver.cpp +++ b/src/sql/resolver/dcl/ob_grant_resolver.cpp @@ -813,29 +813,78 @@ int ObGrantResolver::resolve_col_names( 1. username dup 2. grant role can not with grant option 3. grant role can not reference, index priv */ -int ObGrantResolver::check_user_dup_and_role_grant_option( +int ObGrantResolver::check_user_dup( ObSchemaGetterGuard *guard, ObIArray &user_name_array, const ObGrantStmt *grant_stmt, const ObString& user_name, const ObString& host_name, - const ObString& priv_user_name) + const ObString& priv_user_name, + bool &contain_role, + bool &is_all_role) { int ret = OB_SUCCESS; CK (grant_stmt != NULL); if (ObSchemaChecker::is_ora_priv_check()) { /* 1. check user dup */ - if (has_exist_in_array(user_name_array, user_name)) { + const ObUserInfo *user_info = NULL; + uint64_t tenant_id = OB_INVALID_ID; + if (OB_ISNULL(params_.session_info_) || OB_ISNULL(guard)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", K(ret)); + } else if (has_exist_in_array(user_name_array, user_name)) { ret = OB_ERR_DUPLICATE_USERNAME_IN_LIST; LOG_WARN("user name dup", K(user_name), K(ret)); } else if (grant_stmt->get_database_name() != user_name && user_name == priv_user_name) { ret = OB_ERR_YOU_MAY_NOT_REVOKE_PRIVILEGES_FROM_YOURSELF; LOG_WARN("grant to self", K(user_name), K(ret)); + } else if (OB_FAIL(user_name_array.push_back(user_name))) { + LOG_WARN("failed to push back user name", K(ret), K(user_name)); + } else if (FALSE_IT(tenant_id = params_.session_info_->get_effective_tenant_id())) { + // do nothing + } else if (OB_FAIL(guard->get_user_info(tenant_id, user_name, host_name, user_info))) { + LOG_WARN("failed to get user info", K(ret), K(tenant_id), K(user_name), K(host_name)); + } else if (OB_ISNULL(user_info)) { + ret = OB_USER_NOT_EXIST; + LOG_WARN("user is not exist", K(ret), K(tenant_id), K(user_name), K(host_name)); } else { - OZ (user_name_array.push_back(user_name)); + contain_role |= user_info->is_role(); + is_all_role &= user_info->is_role(); } + } + return ret; +} + +int ObGrantResolver::rebuild_table_priv( + ObGrantStmt *grant_stmt, + bool is_owner, + const bool is_all_role) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(grant_stmt)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null stmt", K(ret)); + } else if (grant_stmt->is_grant_all_tab_priv()) { + share::ObRawObjPrivArray table_priv_array; + OZ (build_table_priv_arary_for_all(grant_stmt, + table_priv_array, + is_owner, + is_all_role)); + OZ (grant_stmt->set_obj_priv_array(table_priv_array)); + } + return ret; +} + +int ObGrantResolver::check_role_grant_option( + const ObGrantStmt *grant_stmt, + const bool contain_role) { + int ret = OB_SUCCESS; + if (OB_ISNULL(grant_stmt)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null stmt", K(ret)); + } else if (ObSchemaChecker::is_ora_priv_check() && contain_role) { bool has_ref_priv = false; bool has_index_priv = false; if (has_exist_in_array(grant_stmt->get_obj_priv_array(), @@ -851,30 +900,17 @@ int ObGrantResolver::check_user_dup_and_role_grant_option( 2. 不能grant reference,其次优先 3. 不能grant index */ if (grant_stmt->get_option() == GRANT_OPTION || has_ref_priv || has_index_priv) { - const ObUserInfo *user_info = NULL; - CK (params_.session_info_ != NULL); - uint64_t tenant_id = params_.session_info_->get_effective_tenant_id(); - CK (guard != NULL); - OZ (guard->get_user_info(tenant_id, user_name, host_name, user_info)); - if (OB_SUCC(ret)) { - if (NULL == user_info) { - ret = OB_USER_NOT_EXIST; - } else if (user_info->is_role()) { - if (grant_stmt->get_option() == GRANT_OPTION) { - ret = OB_ERR_CANNOT_GRANT_TO_A_ROLE_WITH_GRANT_OPTION; - } else if (has_ref_priv) { - ObString str = "REFERENCES"; - ret = OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE; - LOG_USER_ERROR(OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE, - str.length(), str.ptr()); - } else { - CK (has_index_priv); - ObString str = "INDEX"; - ret = OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE; - LOG_USER_ERROR(OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE, - str.length(), str.ptr()); - } - } + if (grant_stmt->get_option() == GRANT_OPTION) { + ret = OB_ERR_CANNOT_GRANT_TO_A_ROLE_WITH_GRANT_OPTION; + } else if (has_ref_priv) { + ObString str = "REFERENCES"; + ret = OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE; + LOG_USER_ERROR(OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE, str.length(), str.ptr()); + } else { + CK (has_index_priv); + ObString str = "INDEX"; + ret = OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE; + LOG_USER_ERROR(OB_ERR_CANNOT_GRANT_STRING_TO_A_ROLE, str.length(), str.ptr()); } } } @@ -999,6 +1035,8 @@ int ObGrantResolver::resolve_grant_obj_privileges( if (OB_SUCC(ret)) { // oracle 模式下 grant 时,如果用户不存在,不允许创建该用户;fix #17900015 bool need_create_user = false; + bool contain_role = false; + bool is_all_role = true; CHECK_COMPATIBILITY_MODE(session_info_); if (!lib::is_oracle_mode()) { need_create_user = (0 == (params_.session_info_->get_sql_mode() @@ -1086,13 +1124,17 @@ int ObGrantResolver::resolve_grant_obj_privileges( //do nothing } } - OZ (check_user_dup_and_role_grant_option(params_.schema_checker_->get_schema_guard(), - user_name_array, - grant_stmt, - user_name, - host_name, - priv_user_name)); + OZ (check_user_dup(params_.schema_checker_->get_schema_guard(), + user_name_array, + grant_stmt, + user_name, + host_name, + priv_user_name, + contain_role, + is_all_role)); } + OZ (rebuild_table_priv(grant_stmt, is_owner, is_all_role)); + OZ (check_role_grant_option(grant_stmt, contain_role)); } }//end of resolve users @@ -1736,7 +1778,8 @@ bool ObGrantResolver::is_ora_obj_priv_type( int ObGrantResolver::build_table_priv_arary_for_all( ObGrantStmt *grant_stmt, share::ObRawObjPrivArray &table_priv_array, - bool is_owner) + bool is_owner, + bool is_role) { int ret = OB_SUCCESS; CK (grant_stmt != NULL); @@ -1773,12 +1816,14 @@ int ObGrantResolver::build_table_priv_arary_for_all( { OZ (table_priv_array.push_back(OBJ_PRIV_ID_ALTER)); OZ (table_priv_array.push_back(OBJ_PRIV_ID_DELETE)); - OZ (table_priv_array.push_back(OBJ_PRIV_ID_INDEX)); OZ (table_priv_array.push_back(OBJ_PRIV_ID_INSERT)); - OZ (table_priv_array.push_back(OBJ_PRIV_ID_REFERENCES)); OZ (table_priv_array.push_back(OBJ_PRIV_ID_SELECT)); OZ (table_priv_array.push_back(OBJ_PRIV_ID_UPDATE)); OZ (table_priv_array.push_back(OBJ_PRIV_ID_FLASHBACK)); + if (OB_SUCC(ret) && !is_role) { + OZ (table_priv_array.push_back(OBJ_PRIV_ID_INDEX)); + OZ (table_priv_array.push_back(OBJ_PRIV_ID_REFERENCES)); + } break; } case share::schema::ObObjectType::SEQUENCE: @@ -1803,9 +1848,11 @@ int ObGrantResolver::build_table_priv_arary_for_all( { OZ (table_priv_array.push_back(OBJ_PRIV_ID_DELETE)); OZ (table_priv_array.push_back(OBJ_PRIV_ID_INSERT)); - OZ (table_priv_array.push_back(OBJ_PRIV_ID_REFERENCES)); OZ (table_priv_array.push_back(OBJ_PRIV_ID_SELECT)); OZ (table_priv_array.push_back(OBJ_PRIV_ID_UPDATE)); + if (OB_SUCC(ret) && !is_role) { + OZ (table_priv_array.push_back(OBJ_PRIV_ID_REFERENCES)); + } break; } case share::schema::ObObjectType::DIRECTORY: @@ -1913,9 +1960,7 @@ int ObGrantResolver::resolve_obj_priv_list_ora( } else if (OB_PRIV_TABLE_LEVEL == grant_level) { if (OB_PRIV_ALL == priv_type) { priv_set |= OB_PRIV_TABLE_ACC; - OZ (build_table_priv_arary_for_all(grant_stmt, - table_priv_array, - is_owner)); + grant_stmt->set_grant_all_tab_priv(true); } else if (priv_type & (~(OB_PRIV_TABLE_ACC | OB_PRIV_GRANT)) && is_ora_obj_priv_type(priv_type) == false) { ret = OB_ERR_MISSING_OR_INVALID_PRIVIEGE; diff --git a/src/sql/resolver/dcl/ob_grant_resolver.h b/src/sql/resolver/dcl/ob_grant_resolver.h index 982cd6a811..b06248505d 100644 --- a/src/sql/resolver/dcl/ob_grant_resolver.h +++ b/src/sql/resolver/dcl/ob_grant_resolver.h @@ -102,13 +102,23 @@ public: share::schema::ObPrivLevel &grant_level, bool &is_directory, bool &explicit_db); - int check_user_dup_and_role_grant_option( + int check_user_dup( share::schema::ObSchemaGetterGuard *guard, ObIArray &user_name_array, const ObGrantStmt *grant_stmt, const ObString& user_name, const ObString& host_name, - const ObString& priv_user_name); + const ObString& priv_user_name, + bool &contain_role, + bool &is_all_role); + int rebuild_table_priv( + ObGrantStmt *grant_stmt, + bool is_owner, + const bool is_all_role); + int check_role_grant_option( + const ObGrantStmt *grant_stmt, + const bool contain_role); + static int resolve_role_sys_obj_all_col_priv_list(const ParseNode *role_sys_list, ObIArray &role_name_array, share::ObRawPrivArray &sys_priv_array); @@ -117,7 +127,8 @@ private: int build_table_priv_arary_for_all( ObGrantStmt *grant_stmt, share::ObRawObjPrivArray &table_priv_array, - bool is_owner); + bool is_owner, + bool is_role); int check_obj_priv_valid( ObGrantStmt *grant_stmt, share::ObRawObjPriv ora_obj_priv); diff --git a/src/sql/resolver/dcl/ob_grant_stmt.cpp b/src/sql/resolver/dcl/ob_grant_stmt.cpp index 81e11f8d47..064407ca53 100644 --- a/src/sql/resolver/dcl/ob_grant_stmt.cpp +++ b/src/sql/resolver/dcl/ob_grant_stmt.cpp @@ -43,7 +43,8 @@ ObGrantStmt::ObGrantStmt(ObIAllocator *name_pool) ins_col_ids_(), upd_col_ids_(), ref_col_ids_(), - ref_query_(NULL) + ref_query_(NULL), + is_grant_all_tab_priv_(false) { } @@ -68,7 +69,8 @@ ObGrantStmt::ObGrantStmt() ins_col_ids_(), upd_col_ids_(), ref_col_ids_(), - ref_query_(NULL) + ref_query_(NULL), + is_grant_all_tab_priv_(false) { } diff --git a/src/sql/resolver/dcl/ob_grant_stmt.h b/src/sql/resolver/dcl/ob_grant_stmt.h index aa17d7616b..7739d028de 100644 --- a/src/sql/resolver/dcl/ob_grant_stmt.h +++ b/src/sql/resolver/dcl/ob_grant_stmt.h @@ -68,6 +68,7 @@ public: int set_ref_col_ids(ObSEArray &col_ids) { return ref_col_ids_.assign(col_ids); } void set_ref_query(ObSelectStmt* ref_query) { ref_query_ = ref_query; } int add_grantee(const common::ObString &grantee); + void set_grant_all_tab_priv(bool is_grant_all) { is_grant_all_tab_priv_ = is_grant_all; } const share::ObRawPrivArray& get_priv_array() const {return sys_priv_array_;} const share::ObRawObjPrivArray& get_obj_priv_array() const {return obj_priv_array_;} @@ -78,6 +79,7 @@ public: ObPrivSet get_priv_set() const { return priv_set_; } uint64_t get_tenant_id() const { return tenant_id_; } const common::ObStrings& get_grantees() const { return grantees_; } + bool is_grant_all_tab_priv() const { return is_grant_all_tab_priv_; } virtual bool cause_implicit_commit() const { return true; } virtual obrpc::ObDDLArg &get_ddl_arg() { return grant_arg_; } @@ -107,6 +109,7 @@ private: ObSEArray upd_col_ids_; ObSEArray ref_col_ids_; ObSelectStmt *ref_query_; // 用于grant 视图时,对视图依赖的table,view等做递归权限check. + bool is_grant_all_tab_priv_; private: DISALLOW_COPY_AND_ASSIGN(ObGrantStmt);