[FEAT MERGE] log4200
Co-authored-by: zhjc1124 <zhjc1124@gmail.com> Co-authored-by: BinChenn <binchenn.bc@gmail.com> Co-authored-by: oceanoverflow <oceanoverflow@gmail.com>
This commit is contained in:
139
src/sql/resolver/ddl/ob_create_standby_tenant_resolver.cpp
Normal file
139
src/sql/resolver/ddl/ob_create_standby_tenant_resolver.cpp
Normal file
@ -0,0 +1,139 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_RESV
|
||||
|
||||
#include "sql/resolver/ddl/ob_create_standby_tenant_resolver.h"
|
||||
#include "sql/resolver/ddl/ob_create_tenant_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_tenant_resolver.h"
|
||||
#include "sql/resolver/expr/ob_raw_expr_util.h"
|
||||
#include "sql/resolver/cmd/ob_variable_set_resolver.h"
|
||||
#include "sql/resolver/ob_resolver_utils.h" // ObResolverUtils
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
using namespace common;
|
||||
using namespace share::schema;
|
||||
namespace sql
|
||||
{
|
||||
|
||||
ObCreateStandbyTenantResolver::ObCreateStandbyTenantResolver(ObResolverParams ¶ms)
|
||||
: ObDDLResolver(params)
|
||||
{
|
||||
}
|
||||
|
||||
ObCreateStandbyTenantResolver::~ObCreateStandbyTenantResolver()
|
||||
{
|
||||
}
|
||||
|
||||
int ObCreateStandbyTenantResolver::resolve(const ParseNode &parse_tree)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObCreateTenantStmt *mystmt = NULL;
|
||||
|
||||
if (OB_UNLIKELY(T_CREATE_STANDBY_TENANT != parse_tree.type_)
|
||||
|| OB_ISNULL(parse_tree.children_)
|
||||
|| OB_UNLIKELY(4 != parse_tree.num_child_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid param", K(ret), K(parse_tree.type_), K(parse_tree.num_child_), KP(parse_tree.children_));
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_UNLIKELY(NULL == (mystmt = create_stmt<ObCreateTenantStmt>()))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_ERROR("failed to create stmt");
|
||||
} else {
|
||||
(void)mystmt->set_stmt_type(stmt::T_CREATE_STANDBY_TENANT);
|
||||
stmt_ = mystmt;
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
(void)mystmt->set_create_standby_tenant();
|
||||
}
|
||||
|
||||
/* [if not exists] */
|
||||
if (OB_SUCC(ret)) {
|
||||
if (NULL != parse_tree.children_[0]) {
|
||||
if (OB_UNLIKELY(T_IF_NOT_EXISTS != parse_tree.children_[0]->type_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid parse_tree", KR(ret));
|
||||
} else {
|
||||
mystmt->set_if_not_exist(true);
|
||||
}
|
||||
} else {
|
||||
mystmt->set_if_not_exist(false);
|
||||
}
|
||||
}
|
||||
|
||||
/* tenant name */
|
||||
if (OB_SUCC(ret)) {
|
||||
ObTenantResolver<ObCreateTenantStmt> resolver;
|
||||
if (OB_FAIL(resolver.resolve_tenant_name(mystmt, parse_tree.children_[1]))) {
|
||||
LOG_WARN("resolve tenant name failed", KR(ret));
|
||||
}
|
||||
}
|
||||
|
||||
/* log restore source */
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(resolve_log_restore_source_(mystmt, parse_tree.children_[2]))) {
|
||||
LOG_WARN("resolve log_restore_source failed", KR(ret));
|
||||
}
|
||||
}
|
||||
|
||||
/* tenant options */
|
||||
if (OB_SUCC(ret)) {
|
||||
if (NULL != parse_tree.children_[3]) {
|
||||
if (OB_UNLIKELY(T_TENANT_OPTION_LIST != parse_tree.children_[3]->type_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid option node type", K(parse_tree.children_[3]->type_), KR(ret));
|
||||
} else {
|
||||
ObTenantResolver<ObCreateTenantStmt> resolver;
|
||||
ret = resolver.resolve_tenant_options(mystmt, parse_tree.children_[3], session_info_, *allocator_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCreateStandbyTenantResolver::resolve_log_restore_source_(ObCreateTenantStmt *stmt, ParseNode *log_restore_source_node) const
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
if (OB_ISNULL(stmt)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
SQL_LOG(ERROR, "null ptr", KR(ret), KP(stmt));
|
||||
} else if (OB_ISNULL(log_restore_source_node)) {
|
||||
ret = common::OB_INVALID_ARGUMENT;
|
||||
SQL_LOG(WARN, "should specify log restore source", KR(ret));
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "LOG_RESTORE_SOURCE");
|
||||
} else if (OB_UNLIKELY(T_LOG_RESTORE_SOURCE != log_restore_source_node->type_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid parse_tree", KR(ret), K(log_restore_source_node->type_));
|
||||
} else if (OB_ISNULL(log_restore_source_node->children_)) {
|
||||
ret = common::OB_INVALID_ARGUMENT;
|
||||
SQL_LOG(WARN, "log restore source invalid", KR(ret));
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "LOG_RESTORE_SOURCE");
|
||||
} else {
|
||||
ObString log_restore_source("");
|
||||
if (OB_FAIL(ObResolverUtils::resolve_string(log_restore_source_node->children_[0], log_restore_source))) {
|
||||
LOG_WARN("resolve string failed", KR(ret), K(log_restore_source_node->type_));
|
||||
} else {
|
||||
stmt->set_log_restore_source(log_restore_source);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} /* sql */
|
||||
} /* oceanbase */
|
||||
45
src/sql/resolver/ddl/ob_create_standby_tenant_resolver.h
Normal file
45
src/sql/resolver/ddl/ob_create_standby_tenant_resolver.h
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_CREATE_STANDBY_TENANT_RESOLVER_
|
||||
#define OCEANBASE_CREATE_STANDBY_TENANT_RESOLVER_ 1
|
||||
|
||||
#include "sql/resolver/ddl/ob_create_tenant_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_ddl_resolver.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace sql
|
||||
{
|
||||
class ObCreateStandbyTenantResolver: public ObDDLResolver
|
||||
{
|
||||
public:
|
||||
explicit ObCreateStandbyTenantResolver(ObResolverParams ¶ms);
|
||||
virtual ~ObCreateStandbyTenantResolver();
|
||||
|
||||
virtual int resolve(const ParseNode &parse_tree);
|
||||
private:
|
||||
int resolve_log_restore_source_(ObCreateTenantStmt *stmt, ParseNode *log_restore_source_node) const;
|
||||
|
||||
private:
|
||||
// disallow copy
|
||||
DISALLOW_COPY_AND_ASSIGN(ObCreateStandbyTenantResolver);
|
||||
// function members
|
||||
|
||||
private:
|
||||
// data members
|
||||
};
|
||||
|
||||
} // end namespace sql
|
||||
} // end namespace oceanbase
|
||||
|
||||
#endif /* OCEANBASE_CREATE_STANDBY_TENANT_RESOLVER_ */
|
||||
@ -78,22 +78,9 @@ int ObCreateTenantResolver::resolve(const ParseNode &parse_tree)
|
||||
}
|
||||
/* tenant name */
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_UNLIKELY(T_IDENT != parse_tree.children_[1]->type_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid parse_tree", K(ret));
|
||||
} else {
|
||||
ObString tenant_name;
|
||||
tenant_name.assign_ptr((char *)(parse_tree.children_[1]->str_value_),
|
||||
static_cast<int32_t>(parse_tree.children_[1]->str_len_));
|
||||
if (tenant_name.length() >= OB_MAX_TENANT_NAME_LENGTH) {
|
||||
ret = OB_ERR_TOO_LONG_IDENT;
|
||||
LOG_USER_ERROR(OB_ERR_TOO_LONG_IDENT, tenant_name.length(), tenant_name.ptr());
|
||||
} else if (ObString::make_string("seed") == tenant_name) {
|
||||
ret = OB_ERR_INVALID_TENANT_NAME;
|
||||
LOG_ERROR("invalid tenant name", K(tenant_name), K(ret));
|
||||
} else {
|
||||
mystmt->set_tenant_name(tenant_name);
|
||||
}
|
||||
ObTenantResolver<ObCreateTenantStmt> resolver;
|
||||
if (OB_FAIL(resolver.resolve_tenant_name(mystmt, parse_tree.children_[1]))) {
|
||||
LOG_WARN("resolve tenant name failed", KR(ret));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -140,6 +140,15 @@ int ObCreateTenantStmt::set_tcp_invited_nodes(common::ObString value)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObCreateTenantStmt::set_create_standby_tenant()
|
||||
{
|
||||
create_tenant_arg_.is_creating_standby_ = true;
|
||||
}
|
||||
|
||||
void ObCreateTenantStmt::set_log_restore_source(const common::ObString &log_restore_source)
|
||||
{
|
||||
create_tenant_arg_.log_restore_source_ = log_restore_source;
|
||||
}
|
||||
|
||||
} /* sql */
|
||||
} /* oceanbase */
|
||||
|
||||
@ -53,6 +53,8 @@ public:
|
||||
int assign_variable_nodes(const common::ObIArray<ObVariableSetStmt::VariableSetNode> &other);
|
||||
int set_default_tablegroup_name(const common::ObString &tablegroup_name);
|
||||
virtual obrpc::ObDDLArg &get_ddl_arg() { return create_tenant_arg_; }
|
||||
void set_create_standby_tenant();
|
||||
void set_log_restore_source(const common::ObString &log_restore_source);
|
||||
private:
|
||||
obrpc::ObCreateTenantArg create_tenant_arg_;
|
||||
common::ObArray<ObVariableSetStmt::VariableSetNode, common::ModulePageAllocator, true> sys_var_nodes_;
|
||||
|
||||
@ -48,8 +48,11 @@ public:
|
||||
int resolve_tenant_options(T *stmt, ParseNode *node, ObSQLSessionInfo *session_info, common::ObIAllocator &allocator);
|
||||
const common::ObBitSet<> &get_alter_option_bitset() const { return alter_option_bitset_; };
|
||||
bool is_modify_read_only() const { return modify_read_only_; }
|
||||
int resolve_tenant_name(T *stmt, ParseNode *node) const;
|
||||
|
||||
private:
|
||||
int resolve_tenant_option(T *stmt, ParseNode *node, ObSQLSessionInfo *session_info, common::ObIAllocator &allocator);
|
||||
int check_support_option(const T *stmt, const ParseNode *node);
|
||||
int resolve_zone_list(T *stmt, ParseNode *node) const;
|
||||
int resolve_resource_pool_list(T *stmt, ParseNode *node) const;
|
||||
private:
|
||||
@ -100,6 +103,8 @@ int ObTenantResolver<T>::resolve_tenant_option(T *stmt, ParseNode *node,
|
||||
if (OB_ISNULL(stmt)) {
|
||||
ret = common::OB_ERR_UNEXPECTED;
|
||||
SQL_LOG(ERROR, "null ptr", K(ret));
|
||||
} else if (OB_FAIL(check_support_option(stmt, option_node))) {
|
||||
LOG_WARN("failed to check support option", KR(ret), KPC(stmt), KP(option_node));
|
||||
} else if (option_node) {
|
||||
switch (option_node->type_) {
|
||||
case T_REPLICA_NUM: {
|
||||
@ -388,6 +393,75 @@ int ObTenantResolver<T>::resolve_tenant_option(T *stmt, ParseNode *node,
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
int ObTenantResolver<T>::check_support_option(const T *stmt, const ParseNode *node)
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
|
||||
if (OB_ISNULL(stmt)) {
|
||||
ret = common::OB_INVALID_ARGUMENT;
|
||||
SQL_LOG(WARN, "null pointer", KR(ret), KP(stmt));
|
||||
} else if (OB_NOT_NULL(node)) {
|
||||
if (stmt->get_stmt_type() == stmt::T_CREATE_STANDBY_TENANT) {
|
||||
switch (node->type_) {
|
||||
case T_REPLICA_NUM: {
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "replica_num");
|
||||
}
|
||||
case T_CHARSET: {
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "charset");
|
||||
}
|
||||
case T_COLLATION: {
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "collation");
|
||||
}
|
||||
case T_ENABLE_ARBITRATION_SERVICE: {
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "enable_arbitration_service");
|
||||
}
|
||||
case T_ZONE_LIST: {
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "zone_list");
|
||||
}
|
||||
case T_READ_ONLY: {
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "read_only");
|
||||
}
|
||||
case T_LOGONLY_REPLICA_NUM: {
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "logonly_replica_num");
|
||||
}
|
||||
case T_DEFAULT_TABLEGROUP: {
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "default_tablegroup");
|
||||
}
|
||||
case T_PROGRESSIVE_MERGE_NUM: {
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "progressive_merge_num");
|
||||
}
|
||||
case T_ENABLE_EXTENDED_ROWID: {
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "enable_extended_rowid");
|
||||
}
|
||||
{
|
||||
// not support option
|
||||
ret = common::OB_INVALID_ARGUMENT;
|
||||
SQL_LOG(WARN, "invalid argument", KR(ret), K(node->type_));
|
||||
break;
|
||||
}
|
||||
|
||||
case T_LOCALITY:
|
||||
case T_PRIMARY_ZONE:
|
||||
case T_TENANT_RESOURCE_POOL_LIST:
|
||||
case T_COMMENT: {
|
||||
// support option
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
/* won't be here */
|
||||
ret = common::OB_ERR_UNEXPECTED;
|
||||
SQL_LOG(ERROR, "code should not reach here", KR(ret));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
int ObTenantResolver<T>::resolve_zone_list(T *stmt, ParseNode *node) const
|
||||
{
|
||||
@ -445,6 +519,35 @@ int ObTenantResolver<T>::resolve_resource_pool_list(T *stmt, ParseNode *node) co
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
int ObTenantResolver<T>::resolve_tenant_name(T *stmt, ParseNode *node) const
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
if (OB_ISNULL(node) || OB_ISNULL(stmt)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
SQL_LOG(ERROR, "null ptr", KR(ret), KP(node), KP(stmt));
|
||||
} else if (OB_UNLIKELY(T_IDENT != node->type_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_LOG(ERROR, "invalid parse_tree", KR(ret));
|
||||
} else {
|
||||
ObString tenant_name;
|
||||
tenant_name.assign_ptr((char *)(node->str_value_),
|
||||
static_cast<int32_t>(node->str_len_));
|
||||
if (tenant_name.length() >= OB_MAX_TENANT_NAME_LENGTH) {
|
||||
ret = OB_ERR_TOO_LONG_IDENT;
|
||||
LOG_USER_ERROR(OB_ERR_TOO_LONG_IDENT, tenant_name.length(), tenant_name.ptr());
|
||||
} else if (ObString::make_string("seed") == tenant_name) {
|
||||
ret = OB_ERR_INVALID_TENANT_NAME;
|
||||
LOG_ERROR("invalid tenant name", K(tenant_name), KR(ret));
|
||||
} else {
|
||||
stmt->set_tenant_name(tenant_name);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
|
||||
|
||||
@ -56,6 +56,7 @@
|
||||
#include "sql/resolver/ddl/ob_drop_routine_resolver.h"
|
||||
#include "sql/resolver/ddl/ob_trigger_resolver.h"
|
||||
#include "sql/resolver/ddl/ob_optimize_resolver.h"
|
||||
#include "sql/resolver/ddl/ob_create_standby_tenant_resolver.h"
|
||||
#include "ddl/ob_create_routine_resolver.h"
|
||||
#include "ddl/ob_drop_routine_resolver.h"
|
||||
#include "ddl/ob_alter_routine_resolver.h"
|
||||
@ -267,6 +268,10 @@ int ObResolver::resolve(IsPrepared if_prepared, const ParseNode &parse_tree, ObS
|
||||
REGISTER_STMT_RESOLVER(CreateTenant);
|
||||
break;
|
||||
}
|
||||
case T_CREATE_STANDBY_TENANT: {
|
||||
REGISTER_STMT_RESOLVER(CreateStandbyTenant);
|
||||
break;
|
||||
}
|
||||
case T_DROP_TENANT: {
|
||||
REGISTER_STMT_RESOLVER(DropTenant);
|
||||
break;
|
||||
|
||||
@ -1783,6 +1783,7 @@ stmt::StmtType ObResolverUtils::get_stmt_type_by_item_type(const ObItemType item
|
||||
SET_STMT_TYPE(T_ALTER_RESOURCE_UNIT);
|
||||
SET_STMT_TYPE(T_DROP_RESOURCE_UNIT);
|
||||
SET_STMT_TYPE(T_CREATE_TENANT);
|
||||
SET_STMT_TYPE(T_CREATE_STANDBY_TENANT);
|
||||
SET_STMT_TYPE(T_DROP_TENANT);
|
||||
SET_STMT_TYPE(T_MODIFY_TENANT);
|
||||
SET_STMT_TYPE(T_LOCK_TENANT);
|
||||
|
||||
@ -264,6 +264,7 @@ public:
|
||||
|| stmt_type == stmt::T_ALTER_RESOURCE_UNIT
|
||||
|| stmt_type == stmt::T_DROP_RESOURCE_UNIT
|
||||
|| stmt_type == stmt::T_CREATE_TENANT
|
||||
|| stmt_type == stmt::T_CREATE_STANDBY_TENANT
|
||||
|| stmt_type == stmt::T_DROP_TENANT
|
||||
|| stmt_type == stmt::T_MODIFY_TENANT
|
||||
|| stmt_type == stmt::T_LOCK_TENANT
|
||||
@ -393,6 +394,7 @@ public:
|
||||
|| stmt_type == stmt::T_ALTER_RESOURCE_UNIT
|
||||
|| stmt_type == stmt::T_DROP_RESOURCE_UNIT
|
||||
|| stmt_type == stmt::T_CREATE_TENANT
|
||||
|| stmt_type == stmt::T_CREATE_STANDBY_TENANT
|
||||
|| stmt_type == stmt::T_DROP_TENANT
|
||||
|| stmt_type == stmt::T_MODIFY_TENANT
|
||||
|| stmt_type == stmt::T_LOCK_TENANT
|
||||
@ -452,6 +454,7 @@ public:
|
||||
|| stmt_type == stmt::T_ALTER_RESOURCE_UNIT
|
||||
|| stmt_type == stmt::T_DROP_RESOURCE_UNIT
|
||||
|| stmt_type == stmt::T_CREATE_TENANT
|
||||
|| stmt_type == stmt::T_CREATE_STANDBY_TENANT
|
||||
|| stmt_type == stmt::T_DROP_TENANT
|
||||
|| stmt_type == stmt::T_MODIFY_TENANT
|
||||
|| stmt_type == stmt::T_LOCK_TENANT
|
||||
|
||||
@ -281,6 +281,7 @@ OB_STMT_TYPE_DEF_UNKNOWN_AT(T_REMOVE_ARBITRATION_SERVICE, get_sys_tenant_alter_s
|
||||
OB_STMT_TYPE_DEF_UNKNOWN_AT(T_REPLACE_ARBITRATION_SERVICE, get_sys_tenant_alter_system_priv, 282)
|
||||
OB_STMT_TYPE_DEF_UNKNOWN_AT(T_SHOW_SEQUENCES, err_stmt_type_priv, 283)
|
||||
OB_STMT_TYPE_DEF_UNKNOWN_AT(T_BACKUP_KEY, get_sys_tenant_alter_system_priv, 284)
|
||||
OB_STMT_TYPE_DEF_UNKNOWN_AT(T_CREATE_STANDBY_TENANT, get_sys_tenant_super_priv, 285)
|
||||
|
||||
OB_STMT_TYPE_DEF_UNKNOWN_AT(T_MAX, err_stmt_type_priv, 500)
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user