Files
oceanbase/src/sql/resolver/cmd/ob_show_resolver.cpp

2978 lines
156 KiB
C++

/**
* 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/cmd/ob_show_resolver.h"
#include "share/inner_table/ob_inner_table_schema.h"
#include "share/schema/ob_priv_type.h"
#include "share/schema/ob_schema_utils.h"
#include "sql/session/ob_sql_session_info.h"
#include "sql/ob_sql_context.h"
#include "sql/parser/ob_parser.h"
#include "lib/charset/ob_charset.h"
#include "observer/ob_server_struct.h"
using namespace oceanbase::common;
using namespace oceanbase::share;
using namespace oceanbase::share::schema;
namespace oceanbase
{
namespace sql
{
ObShowResolver::ObShowResolver(ObResolverParams &params)
: ObSelectResolver(params)
{
params_.is_from_show_resolver_ = true;
}
ObShowResolver::~ObShowResolver()
{
}
#define GEN_SQL_STEP_1(SHOW_STMT_TYPE, args...) \
do { \
if (OB_SUCC(ret)) { \
show_resv_ctx.like_column_ = SHOW_STMT_TYPE##_LIKE == NULL ? ObString::make_string("") : \
ObString::make_string(SHOW_STMT_TYPE##_LIKE); \
if (OB_SUCC(ret) && OB_FAIL(sql_gen.init(params_.allocator_))) { \
LOG_WARN("fail to init sql string generator", K(ret)); \
} else if (OB_FAIL(sql_gen.gen_select_str(SHOW_STMT_TYPE##_SELECT, ##args))) { \
LOG_WARN("fail to generate select string", K(ret)); \
} else { /*do nothing*/ } \
} \
} while(0)
#define GEN_SQL_STEP_2(SHOW_STMT_TYPE, args...) \
do { \
if (OB_SUCC(ret)) { \
if (is_oracle_mode && OB_FAIL(sql_gen.gen_from_str(SHOW_STMT_TYPE##_ORA_SUBQUERY, ##args))) { \
LOG_WARN("fail to generate from string in oracle mode", K(ret)); \
} else if (!is_oracle_mode && OB_FAIL(sql_gen.gen_from_str(SHOW_STMT_TYPE##_SUBQUERY, ##args))) { \
LOG_WARN("fail to generate from string", K(ret)); \
} else { \
sql_gen.assign_sql_str(select_sql); \
} \
} \
} while(0)
#define REAL_NAME(a, b) ((!is_oracle_mode) ? (a) : (b))
int ObShowResolver::resolve(const ParseNode &parse_tree)
{
int ret = OB_SUCCESS;
uint64_t real_tenant_id = OB_INVALID_ID;
uint64_t sql_tenant_id = OB_INVALID_TENANT_ID;
ObString database_name;
ObSessionPrivInfo session_priv;
ObString select_sql;
ObString user_name;
ObString host_name;
ObSynonymChecker synonym_checker;
uint64_t user_id = OB_INVALID_ID;
ObShowResolverContext show_resv_ctx;
if (OB_UNLIKELY(NULL == session_info_
|| NULL == params_.allocator_
|| NULL == schema_checker_)) {
ret = OB_NOT_INIT;
LOG_WARN("data member is not init",
K(ret),
K(session_info_),
K(params_.allocator_),
K(schema_checker_));
} else if (OB_UNLIKELY(parse_tree.type_ < T_SHOW_TABLES || parse_tree.type_ > T_SHOW_GRANTS) && (parse_tree.type_ != T_SHOW_TRIGGERS)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected parse tree type", K(ret), K(parse_tree.type_));
} else {
real_tenant_id = session_info_->get_effective_tenant_id();
sql_tenant_id = ObSchemaUtils::get_extract_tenant_id(real_tenant_id, real_tenant_id);
database_name.assign_ptr(session_info_->get_database_name().ptr(),
session_info_->get_database_name().length());
user_name.assign_ptr(session_info_->get_user_name().ptr(),
session_info_->get_user_name().length());
host_name.assign_ptr(session_info_->get_host_name().ptr(),
session_info_->get_host_name().length());
user_id = session_info_->get_user_id();
session_info_->get_session_priv_info(session_priv);
}
if (OB_SUCC(ret)) {
show_resv_ctx.cur_tenant_id_ = real_tenant_id;
show_resv_ctx.actual_tenant_id_ = real_tenant_id;
show_resv_ctx.database_name_ = ObString("oceanbase");
show_resv_ctx.parse_tree_ = &parse_tree;
}
if (OB_SUCC(ret)) {
common::ObSEArray<int64_t, 4> subquery_params;
ObArenaAllocator alloc;
ObStmtNeedPrivs stmt_need_privs;
stmt_need_privs.need_privs_.set_allocator(&alloc);
ObSqlStrGenerator sql_gen;
bool is_oracle_mode = lib::is_oracle_mode();
switch (parse_tree.type_) {
case T_SHOW_TABLES: {
if (is_oracle_mode) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "show table in oracle mode is");
} else if (OB_UNLIKELY(parse_tree.num_child_ != 3 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_), K(parse_tree.children_));
} else if (OB_UNLIKELY(NULL == parse_tree.children_[2])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL",
K(ret),
K(parse_tree.children_[2]));
} else {
show_resv_ctx.condition_node_ = parse_tree.children_[1];
show_resv_ctx.stmt_type_ = stmt::T_SHOW_TABLES;
ParseNode *condition_node = show_resv_ctx.condition_node_;
ObString show_db_name;
uint64_t show_db_id = OB_INVALID_ID;
if (OB_FAIL(get_database_info(parse_tree.children_[0],
database_name,
real_tenant_id,
show_resv_ctx,
show_db_id))) {
LOG_WARN("fail to get database info", K(ret));
} else if (OB_UNLIKELY(OB_INVALID_ID == show_db_id)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("database id is invalid", K(ret), K(show_db_id));
} else {
show_db_name = show_resv_ctx.show_database_name_;
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 {
LOG_WARN("fail to check priv", K(ret));
}
} else {
if (0 == parse_tree.children_[2]->value_) {
if (NULL != condition_node && T_LIKE_CLAUSE == condition_node->type_) {
if (OB_UNLIKELY(condition_node->num_child_ != 2
|| NULL == condition_node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid like parse node",
K(ret),
K(condition_node->num_child_),
K(condition_node->children_));
} else if (OB_UNLIKELY(NULL == condition_node->children_[0]
|| NULL == condition_node->children_[1])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid like parse node",
K(ret),
K(condition_node->num_child_),
K(condition_node->children_[0]),
K(condition_node->children_[1]));
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_TABLES_LIKE,
show_resv_ctx.show_database_name_.length(),
show_resv_ctx.show_database_name_.ptr(),
static_cast<ObString::obstr_size_t>(condition_node->children_[0]->str_len_),//cast int64_t to obstr_size_t
condition_node->children_[0]->str_value_);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_TABLES_LIKE, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_SHOW_TABLES_TNAME, show_db_id);
}
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_TABLES, show_resv_ctx.show_database_name_.length(),
show_resv_ctx.show_database_name_.ptr());
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_TABLES, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_SHOW_TABLES_TNAME, show_db_id);
}
} else if (1 == parse_tree.children_[2]->value_) {
if (NULL != condition_node && T_LIKE_CLAUSE == condition_node->type_) {
if (OB_UNLIKELY(condition_node->num_child_ != 2
|| NULL == condition_node->children_[0]
|| NULL == condition_node->children_[1])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid like parse node",
K(ret),
K(condition_node->num_child_),
K(condition_node->children_[0]),
K(condition_node->children_[1]));
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_FULL_TABLES_LIKE,
show_resv_ctx.show_database_name_.length(),
show_resv_ctx.show_database_name_.ptr(),
static_cast<ObString::obstr_size_t>(condition_node->children_[0]->str_len_),//cast int64_t to obstr_size_t
condition_node->children_[0]->str_value_);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_FULL_TABLES_LIKE, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_SHOW_TABLES_TNAME, show_db_id);
}
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_FULL_TABLES, show_resv_ctx.show_database_name_.length(),
show_resv_ctx.show_database_name_.ptr());
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_FULL_TABLES, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_SHOW_TABLES_TNAME, show_db_id);
}
} else {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("node value unexpected", K(parse_tree.value_));
break;
}
}
//change where condition :Tables_in_xxx=>table_name
if (OB_SUCCESS == ret && NULL != condition_node && T_WHERE_CLAUSE == condition_node->type_) {
char *column_name = NULL;
int64_t tmp_pos = 0;
if (OB_FAIL(NULL == (column_name = static_cast<char *>(params_.allocator_->alloc(OB_MAX_COLUMN_NAME_BUF_LENGTH))))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("failed to alloc column name buf", K(column_name));
} else if (OB_FAIL(databuff_printf(column_name,
OB_MAX_COLUMN_NAME_BUF_LENGTH,
tmp_pos,
"tables_in_%.*s",
show_resv_ctx.show_database_name_.length(),
show_resv_ctx.show_database_name_.ptr()))) {
LOG_WARN("fail to add database name", K(show_resv_ctx.show_database_name_.ptr()));
break;
} else if (FALSE_IT(show_resv_ctx.column_name_ = ObString::make_string(column_name))){
//won't be here
} else if(OB_FAIL(replace_where_clause(condition_node->children_[0], show_resv_ctx))) {
LOG_WARN("fail to replace where clause", K(condition_node->children_[0]));
break;
}
}
}
}
break;
}
case T_SHOW_DATABASES: {
[&] {
if (is_oracle_mode) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "show database in oracle mode is");
} else if (OB_UNLIKELY(parse_tree.num_child_ != 2 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_), K(parse_tree.children_));
} else {
show_resv_ctx.condition_node_ = parse_tree.children_[0];
ParseNode *condition_node = show_resv_ctx.condition_node_;
show_resv_ctx.stmt_type_ = stmt::T_SHOW_DATABASES;
bool show_db_status = parse_tree.children_[1] != NULL ? true : false;
if (NULL != show_resv_ctx.condition_node_ && T_LIKE_CLAUSE == show_resv_ctx.condition_node_->type_) {
if (OB_UNLIKELY(show_resv_ctx.condition_node_->num_child_ != 2
|| NULL == show_resv_ctx.condition_node_->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid like parse node",
K(ret),
K(show_resv_ctx.condition_node_->num_child_),
K(show_resv_ctx.condition_node_->children_));
} else if (OB_UNLIKELY(NULL == condition_node->children_[0]
|| NULL == condition_node->children_[1])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid like parse node",
K(ret),
K(condition_node->num_child_),
K(condition_node->children_[0]),
K(condition_node->children_[1]));
} else {
if (show_db_status) {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_DATABASES_STATUS_LIKE,
static_cast<ObString::obstr_size_t>(show_resv_ctx.condition_node_->children_[0]->str_len_),//cast int64_t to obstr_size_t
show_resv_ctx.condition_node_->children_[0]->str_value_);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_DATABASES_STATUS_LIKE, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_DATABASE_STATUS_TNAME);
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_DATABASES_LIKE,
static_cast<ObString::obstr_size_t>(show_resv_ctx.condition_node_->children_[0]->str_len_),//cast int64_t to obstr_size_t
show_resv_ctx.condition_node_->children_[0]->str_value_);
if (is_oracle_mode) {
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_DATABASES_LIKE, OB_SYS_DATABASE_NAME, OB_ALL_DATABASE_TNAME, sql_tenant_id,
OB_RECYCLEBIN_SCHEMA_NAME, OB_PUBLIC_SCHEMA_NAME, OB_SYS_DATABASE_NAME);
} else {
// 多加OB_PUBLIC_SCHEMA_NAME为了匹配三个参数
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_DATABASES_LIKE, OB_SYS_DATABASE_NAME, OB_ALL_DATABASE_TNAME, sql_tenant_id,
OB_RECYCLEBIN_SCHEMA_NAME, OB_PUBLIC_SCHEMA_NAME, OB_PUBLIC_SCHEMA_NAME);
}
}
}
} else {
if (show_db_status) {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_DATABASES_STATUS);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_DATABASES_STATUS, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_DATABASE_STATUS_TNAME);
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_DATABASES);
if (is_oracle_mode) {
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_DATABASES, OB_SYS_DATABASE_NAME, OB_ALL_DATABASE_TNAME, sql_tenant_id,
OB_RECYCLEBIN_SCHEMA_NAME, OB_PUBLIC_SCHEMA_NAME, OB_SYS_DATABASE_NAME);
} else {
// 多加OB_PUBLIC_SCHEMA_NAME为了匹配三个参数
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_DATABASES, OB_SYS_DATABASE_NAME, OB_ALL_DATABASE_TNAME, sql_tenant_id,
OB_RECYCLEBIN_SCHEMA_NAME, OB_PUBLIC_SCHEMA_NAME, OB_PUBLIC_SCHEMA_NAME);
}
}
}
}
}();
break;
}
case T_SHOW_VARIABLES: {
[&] {
if (OB_UNLIKELY(parse_tree.num_child_ != 2 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_), K(parse_tree.children_));
} else if (OB_UNLIKELY(NULL == parse_tree.children_[0])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL",
K(ret),
K(parse_tree.children_[0]));
} else {
show_resv_ctx.condition_node_ = parse_tree.children_[1];
show_resv_ctx.stmt_type_ = stmt::T_SHOW_VARIABLES;
show_resv_ctx.global_scope_ = 1 == parse_tree.children_[0]->value_ ? true : false;
if (true == show_resv_ctx.global_scope_) {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_GLOBAL_VARIABLES);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_GLOBAL_VARIABLES, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_TENANT_VIRTUAL_GLOBAL_VARIABLE_TNAME, OB_TENANT_VIRTUAL_GLOBAL_VARIABLE_ORA_TNAME));
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_VARIABLES);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_VARIABLES, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_TENANT_VIRTUAL_SESSION_VARIABLE_TNAME, OB_TENANT_VIRTUAL_SESSION_VARIABLE_ORA_TNAME));
}
}
}();
break;
}
case T_SHOW_COLUMNS: {
[&] {
// desc table
if (OB_UNLIKELY(parse_tree.num_child_ != 4 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_), K(parse_tree.children_));
} else if (OB_UNLIKELY(NULL == parse_tree.children_[0])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL",
K(ret),
K(parse_tree.children_[0]));
} else {
ObString show_db_name;
uint64_t show_db_id = OB_INVALID_ID;
ObString show_table_name;
uint64_t show_table_id = OB_INVALID_ID;
bool is_view;
show_resv_ctx.condition_node_ = parse_tree.children_[3];
show_resv_ctx.stmt_type_ = stmt::T_SHOW_COLUMNS;
if (OB_FAIL(resolve_show_from_table(parse_tree.children_[1], parse_tree.children_[2],
database_name.empty(), T_SHOW_COLUMNS, real_tenant_id,
show_db_name, show_db_id, show_table_name,
show_table_id, is_view, synonym_checker))) {
LOG_WARN("fail to resolve show from table", K(ret));
} else if (!is_oracle_mode) {
if (OB_FAIL(stmt_need_privs.need_privs_.init(3))) {
LOG_WARN("fail to init need privs array", K(ret));
} else {
ObNeedPriv need_priv;
//Priv check: global select || db select || table acc
need_priv.priv_level_ = OB_PRIV_USER_LEVEL;
need_priv.priv_set_ = OB_PRIV_SELECT;
stmt_need_privs.need_privs_.push_back(need_priv);
need_priv.priv_level_ = OB_PRIV_DB_LEVEL;
need_priv.priv_set_ = OB_PRIV_SELECT;
need_priv.db_ = show_db_name;
stmt_need_privs.need_privs_.push_back(need_priv);
need_priv.priv_level_ = OB_PRIV_TABLE_LEVEL;
need_priv.priv_set_ = OB_PRIV_TABLE_ACC;
need_priv.db_ = show_db_name;
need_priv.table_ = show_table_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_TABLE_PRIVILEGE == ret) {
LOG_USER_ERROR(OB_ERR_NO_TABLE_PRIVILEGE, (int)strlen("SELECT"), "SELECT",
session_priv.user_name_.length(), session_priv.user_name_.ptr(),
session_priv.host_name_.length(),session_priv.host_name_.ptr(),
show_table_name.length(), show_table_name.ptr());
} else {
LOG_WARN("fail to check priv", K(ret));
}
}
}
}
if (OB_SUCC(ret)) {
if (1 == parse_tree.children_[0]->value_) {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_FULL_COLUMNS);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_FULL_COLUMNS, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_TENANT_VIRTUAL_TABLE_COLUMN_TNAME, OB_TENANT_VIRTUAL_TABLE_COLUMN_ORA_TNAME), show_table_id);
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_COLUMNS);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_COLUMNS, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_TENANT_VIRTUAL_TABLE_COLUMN_TNAME, OB_TENANT_VIRTUAL_TABLE_COLUMN_ORA_TNAME), show_table_id);
}
}
}
}();
break;
}
case T_SHOW_CREATE_DATABASE: {
[&] {
if (is_oracle_mode) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "show create database in oracle mode is");
} else if (OB_UNLIKELY(parse_tree.num_child_ != 2 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_), K(parse_tree.children_));
} else if (OB_UNLIKELY(NULL == parse_tree.children_[1])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL",
K(ret),
K(parse_tree.children_[1]));
} else {
ObString show_db_name;
uint64_t show_db_id = OB_INVALID_ID;
show_resv_ctx.stmt_type_ = stmt::T_SHOW_CREATE_DATABASE;
if (OB_FAIL(resolve_show_from_database(*parse_tree.children_[1],
real_tenant_id,
show_db_id,
show_db_name))) {
LOG_WARN("fail to resolve show database", K(ret), K(real_tenant_id));
} 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 {
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);
}
}
}();
break;
}
case T_SHOW_CREATE_VIEW:
case T_SHOW_CREATE_TABLE: {
[&] {
if (OB_UNLIKELY(parse_tree.num_child_ != 1 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_), K(parse_tree.children_));
} else {
ObString show_db_name;
uint64_t show_db_id = OB_INVALID_ID;
ObString show_table_name;
uint64_t show_table_id = OB_INVALID_ID;
bool is_view = false;
bool allow_show = false;
if (OB_FAIL(resolve_show_from_table(parse_tree.children_[0], NULL, database_name.empty(),
parse_tree.type_, real_tenant_id, show_db_name,
show_db_id, show_table_name, show_table_id, is_view, synonym_checker))) {
LOG_WARN("fail to resolve show from table", K(ret));
}
if (OB_FAIL(ret)) {
} else if (T_SHOW_CREATE_VIEW == parse_tree.type_ || is_view) {
if (ObSchemaChecker::is_ora_priv_check()) {
} else {
ObNeedPriv need_priv;
need_priv.db_ = show_db_name;
need_priv.table_ = show_table_name;
need_priv.priv_set_ = OB_PRIV_SHOW_VIEW | OB_PRIV_SELECT;
need_priv.priv_level_ = OB_PRIV_TABLE_LEVEL;
if (OB_FAIL(stmt_need_privs.need_privs_.init(1))) {
LOG_WARN("Failed to init stmt need priv", K(ret));
} else if (OB_FAIL(stmt_need_privs.need_privs_.push_back(need_priv))) {
LOG_WARN("Failed to add need priv", K(ret));
} else if (OB_FAIL(schema_checker_->check_priv(session_priv, stmt_need_privs))) {
LOG_WARN("Failed to check acc", K(ret));
} else { }//do nothing
}
} else if (OB_FAIL(schema_checker_->check_table_show(
session_priv, show_db_name, show_table_name, allow_show))) {
LOG_WARN("Check table show error", K(ret));
} else if (!allow_show) {
ret = OB_ERR_NO_TABLE_PRIVILEGE;
LOG_USER_ERROR(OB_ERR_NO_TABLE_PRIVILEGE, static_cast<int>(strlen("SHOW")), "SHOW",
session_priv.user_name_.length(), session_priv.user_name_.ptr(),
session_priv.host_name_.length(),session_priv.host_name_.ptr(),
show_table_name.length(), show_table_name.ptr());
} else { }//do nothing
if (OB_SUCC(ret)) {
show_resv_ctx.stmt_type_ = (parse_tree.type_ == T_SHOW_CREATE_TABLE) ? stmt::T_SHOW_CREATE_TABLE : stmt::T_SHOW_CREATE_VIEW;
if (parse_tree.type_ == T_SHOW_CREATE_VIEW || is_view) {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_CREATE_VIEW);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_CREATE_VIEW, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_TENANT_VIRTUAL_SHOW_CREATE_TABLE_TNAME, OB_TENANT_VIRTUAL_SHOW_CREATE_TABLE_ORA_TNAME), show_table_id);
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_CREATE_TABLE);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_CREATE_TABLE, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_TENANT_VIRTUAL_SHOW_CREATE_TABLE_TNAME, OB_TENANT_VIRTUAL_SHOW_CREATE_TABLE_ORA_TNAME), show_table_id);
}
}
}
}();
break;
}
case T_SHOW_CREATE_PROCEDURE:
case T_SHOW_CREATE_FUNCTION: {
[&] {
if (OB_UNLIKELY(parse_tree.num_child_ != 1 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_), K(parse_tree.children_));
} else {
ObString show_db_name;
uint64_t show_db_id = OB_INVALID_ID;
ObString show_routine_name;
uint64_t show_routine_id = OB_INVALID_ID;
int64_t proc_type = -1;
bool allow_show = false;
if (OB_FAIL(resolve_show_from_routine(parse_tree.children_[0], NULL, database_name.empty(),
parse_tree.type_, real_tenant_id, show_db_name,
show_db_id, show_routine_name, show_routine_id, proc_type))) {
LOG_WARN("fail to resolve show from table", K(ret));
}
if (OB_FAIL(ret)) {
} else if (OB_FAIL(schema_checker_->check_routine_show(
session_priv, show_db_name, show_routine_name, allow_show))) {
LOG_WARN("Check table show error", K(ret));
} else if (!allow_show) {
ret = OB_ERR_NO_TABLE_PRIVILEGE;
LOG_USER_ERROR(OB_ERR_NO_TABLE_PRIVILEGE, static_cast<int>(strlen("SHOW")), "SHOW",
session_priv.user_name_.length(), session_priv.user_name_.ptr(),
session_priv.host_name_.length(), session_priv.host_name_.ptr(),
show_routine_name.length(), show_routine_name.ptr());
} else { }//do nothing
if (OB_SUCC(ret)) {
show_resv_ctx.stmt_type_ = (parse_tree.type_ == T_SHOW_CREATE_PROCEDURE) ? stmt::T_SHOW_CREATE_PROCEDURE : stmt::T_SHOW_CREATE_FUNCTION;
if (parse_tree.type_ == T_SHOW_CREATE_PROCEDURE) {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_CREATE_PROCEDURE);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_CREATE_PROCEDURE, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_TENANT_VIRTUAL_SHOW_CREATE_PROCEDURE_TNAME, OB_TENANT_VIRTUAL_SHOW_CREATE_PROCEDURE_ORA_TNAME), show_routine_id, proc_type);
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_CREATE_FUNCTION);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_CREATE_FUNCTION, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_TENANT_VIRTUAL_SHOW_CREATE_PROCEDURE_TNAME, OB_TENANT_VIRTUAL_SHOW_CREATE_PROCEDURE_ORA_TNAME), show_routine_id, proc_type);
}
}
}
}();
break;
}
case T_SHOW_CREATE_TRIGGER: {
[&] {
if (OB_UNLIKELY(parse_tree.num_child_ != 1 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_),
K(parse_tree.children_));
} else {
ObString show_db_name;
uint64_t show_db_id = OB_INVALID_ID;
ObString show_tg_name;
uint64_t show_tg_id = OB_INVALID_ID;
bool allow_show = false;
if (OB_FAIL(resolve_show_from_trigger(parse_tree.children_[0], NULL,
database_name.empty(),
real_tenant_id, show_db_name,
show_db_id, show_tg_name, show_tg_id))) {
LOG_WARN("fail to resolve show from trigger", K(ret));
}
if (OB_FAIL(ret)) {
} else if (OB_FAIL(schema_checker_->check_trigger_show(session_priv, show_db_name,
show_tg_name, allow_show))) {
LOG_WARN("Check trigger show error", K(ret));
} else if (!allow_show) {
ret = OB_ERR_NO_TABLE_PRIVILEGE;
LOG_USER_ERROR(OB_ERR_NO_TABLE_PRIVILEGE, static_cast<int>(strlen("SHOW")), "SHOW",
session_priv.user_name_.length(), session_priv.user_name_.ptr(),
session_priv.host_name_.length(), session_priv.host_name_.ptr(),
show_tg_name.length(), show_tg_name.ptr());
} else { }//do nothing
if (OB_SUCC(ret)) {
show_resv_ctx.stmt_type_ = stmt::T_SHOW_CREATE_TRIGGER;
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_CREATE_TRIGGER);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_CREATE_TRIGGER,
REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME),
REAL_NAME(OB_TENANT_VIRTUAL_SHOW_CREATE_TRIGGER_TNAME,
OB_TENANT_VIRTUAL_SHOW_CREATE_TRIGGER_ORA_TNAME),
show_tg_id);
}
}
}();
break;
}
case T_SHOW_INDEXES: {
[&] {
if (is_oracle_mode) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "show indexes in oracle mode is");
} else if (OB_UNLIKELY(parse_tree.num_child_ != 3 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_), K(parse_tree.children_));
} else {
ObString show_db_name;
uint64_t show_db_id = OB_INVALID_ID;
ObString show_table_name;
uint64_t show_table_id = OB_INVALID_ID;
ObObj show_table_id_obj;
bool is_view;
show_resv_ctx.condition_node_ = parse_tree.children_[2];
show_resv_ctx.stmt_type_ = stmt::T_SHOW_INDEXES;
if (OB_FAIL(resolve_show_from_table(parse_tree.children_[0], parse_tree.children_[1], database_name.empty(),
T_SHOW_INDEXES, real_tenant_id, show_db_name, show_db_id,
show_table_name, show_table_id, is_view, synonym_checker))) {
LOG_WARN("fail to resolve show from table", K(ret));
} else if (!is_oracle_mode) {
if (OB_FAIL(stmt_need_privs.need_privs_.init(3))) {
LOG_WARN("fail to init need privs array", K(ret));
} else {
ObNeedPriv need_priv;
//Priv check: global select || db select || table acc
need_priv.priv_level_ = OB_PRIV_USER_LEVEL;
need_priv.priv_set_ = OB_PRIV_SELECT;
stmt_need_privs.need_privs_.push_back(need_priv);
need_priv.priv_level_ = OB_PRIV_DB_LEVEL;
need_priv.priv_set_ = OB_PRIV_SELECT;
need_priv.db_ = show_db_name;
stmt_need_privs.need_privs_.push_back(need_priv);
need_priv.priv_level_ = OB_PRIV_TABLE_LEVEL;
need_priv.priv_set_ = OB_PRIV_TABLE_ACC;
need_priv.db_ = show_db_name;
need_priv.table_ = show_table_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_TABLE_PRIVILEGE == ret) {
LOG_USER_ERROR(OB_ERR_NO_TABLE_PRIVILEGE, (int)strlen("SELECT"), "SELECT",
session_priv.user_name_.length(), session_priv.user_name_.ptr(),
session_priv.host_name_.length(),session_priv.host_name_.ptr(),
show_table_name.length(), show_table_name.ptr());
} else {
LOG_WARN("fail to check priv", K(ret));
}
}
}
}
if (OB_SUCC(ret)) {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_INDEXES);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_INDEXES, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_TABLE_INDEX_TNAME, show_table_id);
}
}
}();
break;
}
case T_SHOW_CHARSET: {
[&] {
if (OB_UNLIKELY(parse_tree.num_child_ != 1 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_), K(parse_tree.children_));
} else {
ObSqlStrGenerator sql_gen;
show_resv_ctx.condition_node_ = parse_tree.children_[0];
show_resv_ctx.stmt_type_ = stmt::T_SHOW_CHARSET;
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_CHARSET);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_CHARSET, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_TENANT_VIRTUAL_CHARSET_TNAME, OB_TENANT_VIRTUAL_CHARSET_AGENT_TNAME));
}
}();
break;
}
case T_SHOW_COLLATION: {
[&] {
if (OB_UNLIKELY(parse_tree.num_child_ != 1 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_), K(parse_tree.children_));
} else {
show_resv_ctx.condition_node_ = parse_tree.children_[0];
show_resv_ctx.stmt_type_ = stmt::T_SHOW_COLLATION;
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_COLLATION);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_COLLATION, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_TENANT_VIRTUAL_COLLATION_TNAME, OB_TENANT_VIRTUAL_COLLATION_ORA_TNAME));
}
}();
break;
}
case T_SHOW_TRACE: {
[&] {
if (OB_UNLIKELY(parse_tree.num_child_ != 2 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_), K(parse_tree.children_));
} else if (!session_info_->get_control_info().is_valid()) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "If full link tracing is not enabled, show trace is");
} else {
show_resv_ctx.condition_node_ = parse_tree.children_[0];
show_resv_ctx.stmt_type_ = stmt::T_SHOW_TRACE;
bool is_row_traceformat = true;
if (NULL != parse_tree.children_[1]) {
ObString show_format;
show_format.assign_ptr(parse_tree.children_[1]->str_value_,
static_cast<ObString::obstr_size_t>(parse_tree.children_[1]->str_len_));
if (show_format.case_compare("JSON")!=0
&& show_format.case_compare("ROW")!=0) {
ret = OB_NOT_SUPPORTED;
LOG_WARN("show format is wrong", K(ret), K(show_format));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "show format only support json/row, other type is ");
} else {
is_row_traceformat = (show_format.case_compare("ROW")==0);
}
}
if (OB_SUCC(ret)) {
session_info_->set_is_row_traceformat(is_row_traceformat);
if (is_row_traceformat) {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_TRACE);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_TRACE, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_ALL_VIRTUAL_SHOW_TRACE_TNAME, OB_ALL_VIRTUAL_SHOW_TRACE_ORA_TNAME));
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_TRACE_JSON);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_TRACE_JSON, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_ALL_VIRTUAL_SHOW_TRACE_TNAME, OB_ALL_VIRTUAL_SHOW_TRACE_ORA_TNAME));
}
}
}
}();
break;
}
case T_SHOW_GRANTS: {
[&] {
if (OB_UNLIKELY(parse_tree.num_child_ != 1 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong",
K(ret),
K(parse_tree.num_child_),
K(parse_tree.children_));
} else {
uint64_t show_user_id = OB_INVALID_ID;
ObString show_user_name;
ObString show_host_name;
show_resv_ctx.stmt_type_ = stmt::T_SHOW_GRANTS;
if (NULL == parse_tree.children_[0]) {
show_user_id = user_id;
show_user_name = user_name;
show_host_name = host_name;
} else if (2 != parse_tree.children_[0]->num_child_) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("sql_parser parse user error", K(ret));
//0: user name; 1: host name
} else if (OB_ISNULL(parse_tree.children_[0])) {
ret = OB_ERR_PARSE_SQL;
LOG_WARN("The child of user node should not be NULL", K(ret));
} else {
const ParseNode *user_hostname_node = parse_tree.children_[0];
ObString user_name(user_hostname_node->children_[0]->str_len_,
user_hostname_node->children_[0]->str_value_);
ObString host_name;
if (NULL == user_hostname_node->children_[1]) {
host_name.assign_ptr(OB_DEFAULT_HOST_NAME, static_cast<int32_t>(STRLEN(OB_DEFAULT_HOST_NAME)));
} else {
host_name.assign_ptr(user_hostname_node->children_[1]->str_value_,
static_cast<int32_t>(user_hostname_node->children_[1]->str_len_));
}
show_user_name = user_name;
show_host_name = host_name;
if (OB_FAIL(schema_checker_->get_user_id(real_tenant_id,
user_name,
host_name,
show_user_id))) {
LOG_WARN("Get user id error", "tenant_id", real_tenant_id,
K(user_name), K(ret));
}
}
if (OB_SUCC(ret)) {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_GRANTS, show_user_name.length(), show_user_name.ptr(), show_host_name.length(), show_host_name.ptr());
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_GRANTS, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_TENANT_VIRTUAL_PRIVILEGE_GRANT_TNAME, OB_TENANT_VIRTUAL_PRIVILEGE_GRANT_ORA_TNAME), show_user_id);
}
}
}();
break;
}
case T_SHOW_PROCESSLIST:{
if (OB_UNLIKELY(parse_tree.num_child_ != 1 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong",
K(ret),
K(parse_tree.num_child_),
K(parse_tree.children_));
} else if (OB_UNLIKELY(NULL == parse_tree.children_[0])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL",
K(ret),
K(parse_tree.children_[0]));
} else {
ObString database_name;
ObString table_name;
uint64_t priv_tenant_id = session_info_->get_priv_tenant_id();
show_resv_ctx.database_name_ = database_name;
show_resv_ctx.stmt_type_ = stmt::T_SHOW_PROCESSLIST;
if (0 == parse_tree.children_[0]->value_) {
if (OB_SYS_TENANT_ID == priv_tenant_id) {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_SYS_PROCESSLIST);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_SYS_PROCESSLIST, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_ALL_VIRTUAL_PROCESSLIST_TNAME, OB_ALL_VIRTUAL_PROCESSLIST_ORA_TNAME));
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_PROCESSLIST);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_PROCESSLIST, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_ALL_VIRTUAL_PROCESSLIST_TNAME, OB_ALL_VIRTUAL_PROCESSLIST_ORA_TNAME), real_tenant_id);
}
} else if (1 == parse_tree.children_[0]->value_) {
if (OB_SYS_TENANT_ID == priv_tenant_id) {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_SYS_FULL_PROCESSLIST);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_SYS_FULL_PROCESSLIST, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_ALL_VIRTUAL_PROCESSLIST_TNAME, OB_ALL_VIRTUAL_PROCESSLIST_ORA_TNAME));
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_FULL_PROCESSLIST);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_FULL_PROCESSLIST, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_ALL_VIRTUAL_PROCESSLIST_TNAME, OB_ALL_VIRTUAL_PROCESSLIST_ORA_TNAME), real_tenant_id);
}
} else {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected node value", K(parse_tree.value_));
break;
}
}
break;
}
case T_SHOW_TABLE_STATUS: {
[&] {
if (OB_UNLIKELY(parse_tree.num_child_ != 2 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong",
K(ret),
K(parse_tree.num_child_),
K(parse_tree.children_));
} else {
show_resv_ctx.condition_node_ = parse_tree.children_[1];
uint64_t show_db_id;
if (OB_FAIL(get_database_info(parse_tree.children_[0],
database_name,
real_tenant_id,
show_resv_ctx,
show_db_id))) {
LOG_WARN("fail to get database info", K(ret));
} else if (OB_UNLIKELY(OB_INVALID_ID == show_db_id)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("database id is invalid", K(ret), K(show_db_id));
} else {
show_resv_ctx.stmt_type_ = stmt::T_SHOW_TABLE_STATUS;
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_TABLE_STATUS);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_TABLE_STATUS, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_TENANT_VIRTUAL_ALL_TABLE_TNAME, OB_TENANT_VIRTUAL_ALL_TABLE_AGENT_TNAME), show_db_id);
}
}
}();
break;
}
case T_SHOW_PROCEDURE_STATUS: //fallthrough
case T_SHOW_FUNCTION_STATUS: {
[&] {
if (is_oracle_mode) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "show procedure/function status in oracle mode is");
} else if (OB_UNLIKELY(parse_tree.num_child_ != 2 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong",
K(ret),
K(parse_tree.num_child_),
K(parse_tree.children_));
} else {
show_resv_ctx.condition_node_ = parse_tree.children_[1];
uint64_t show_db_id;
if (OB_FAIL(get_database_info(parse_tree.children_[0],
database_name,
real_tenant_id,
show_resv_ctx,
show_db_id))) {
LOG_WARN("fail to get database info", K(ret));
} else if (OB_UNLIKELY(OB_INVALID_ID == show_db_id)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("database id is invalid", K(ret), K(show_db_id));
} else {
int64_t proc_type = T_SHOW_PROCEDURE_STATUS == parse_tree.type_ ? ROUTINE_PROCEDURE_TYPE : ROUTINE_FUNCTION_TYPE;
show_resv_ctx.stmt_type_ = T_SHOW_PROCEDURE_STATUS == parse_tree.type_ ? stmt::T_SHOW_PROCEDURE_STATUS : stmt::T_SHOW_FUNCTION_STATUS;
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_PROCEDURE_STATUS);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_PROCEDURE_STATUS,
OB_SYS_DATABASE_NAME, OB_ALL_ROUTINE_TNAME,
OB_SYS_DATABASE_NAME, OB_ALL_DATABASE_TNAME,
OB_MYSQL_SCHEMA_NAME, OB_PROC_TNAME,
show_db_id, proc_type);
}
}
}();
break;
}
case T_SHOW_TRIGGERS: {
[&] {
if (is_oracle_mode) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "show triggers in oracle mode is");
} else if (OB_UNLIKELY(parse_tree.num_child_ != 2 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong",
K(ret),
K(parse_tree.num_child_),
K(parse_tree.children_));
} else {
show_resv_ctx.condition_node_ = parse_tree.children_[1];
show_resv_ctx.stmt_type_ = stmt::T_SHOW_TRIGGERS;
ParseNode *condition_node = show_resv_ctx.condition_node_;
uint64_t show_db_id = OB_INVALID_ID;
if (OB_FAIL(get_database_info(parse_tree.children_[0],
database_name,
real_tenant_id,
show_resv_ctx,
show_db_id))) {
LOG_WARN("fail to get database info", K(ret));
} else if (OB_UNLIKELY(OB_INVALID_ID == show_db_id)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("database id is invalid", K(ret), K(show_db_id));
} else {
if (NULL != condition_node && T_LIKE_CLAUSE == condition_node->type_) {
if (OB_UNLIKELY(condition_node->num_child_ != 2
|| NULL == condition_node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid like parse node",
K(ret),
K(condition_node->num_child_),
K(condition_node->children_));
} else if (OB_UNLIKELY(NULL == condition_node->children_[0]
|| NULL == condition_node->children_[1])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid like parse node",
K(ret),
K(condition_node->num_child_),
K(condition_node->children_[0]),
K(condition_node->children_[1]));
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_TRIGGERS_LIKE);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_TRIGGERS_LIKE,
OB_INFORMATION_SCHEMA_NAME,
OB_TRIGGERS_TNAME,
OB_SYS_DATABASE_NAME,
OB_ALL_DATABASE_TNAME,
show_db_id);
}
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_TRIGGERS);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_TRIGGERS,
OB_INFORMATION_SCHEMA_NAME,
OB_TRIGGERS_TNAME,
OB_SYS_DATABASE_NAME,
OB_ALL_DATABASE_TNAME,
show_db_id);
}
}
}
}();
break;
}
case T_SHOW_WARNINGS:
case T_SHOW_ERRORS: {
[&] {
int64_t offset = 0;
int64_t row_count = 0;
ParseNode *offset_node = NULL;
ParseNode *row_count_node = NULL;
if (is_oracle_mode) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "show warnings/errors in oracle mode is");
} else if (OB_UNLIKELY(parse_tree.num_child_ != 1 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_), K(parse_tree.children_));
} else {
show_resv_ctx.stmt_type_ = parse_tree.type_ == T_SHOW_WARNINGS ? stmt::T_SHOW_WARNINGS : stmt::T_SHOW_ERRORS;
if (NULL == parse_tree.children_[0]) { // show warnings|errors
if (parse_tree.type_ == T_SHOW_WARNINGS) {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_WARNINGS);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_WARNINGS, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_WARNING_TNAME);
} else if (parse_tree.type_ == T_SHOW_ERRORS) {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_ERRORS);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_ERRORS, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_WARNING_TNAME);
} else {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected node type", K(parse_tree.type_));
}
} else if (NULL != parse_tree.children_[0] && // show warnings|errors limit [offset,] row_count
T_SHOW_LIMIT == parse_tree.children_[0]->type_) {
if (OB_UNLIKELY(parse_tree.children_[0]->num_child_ != 2 || NULL == parse_tree.children_[0]->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.children_[0]->num_child_), K(parse_tree.children_[0]->children_));
} else if (OB_UNLIKELY(NULL == parse_tree.children_[0]->children_[1])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL",
K(ret),
K(parse_tree.children_[0]->children_[0]));
} else {
offset_node = parse_tree.children_[0]->children_[0];
row_count_node = parse_tree.children_[0]->children_[1];
row_count = row_count_node->value_;
offset = NULL != offset_node ? offset_node->value_ : 0;
if (parse_tree.type_ == T_SHOW_WARNINGS) {
if (OB_FAIL(sql_gen.init(params_.allocator_))) {
LOG_WARN("fail to init sql string generator", K(ret));
} else if (OB_FAIL(sql_gen.gen_select_str(ObShowSqlSet::SHOW_WARNINGS_SELECT))) {
LOG_WARN("fail to generate select string", K(ret));
} else if (OB_FAIL(sql_gen.gen_from_str(ObShowSqlSet::SHOW_WARNINGS_SUBQUERY, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_WARNING_TNAME))) {
LOG_WARN("fail to generate from string", K(ret));
} else if (OB_FAIL(sql_gen.gen_limit_str(offset, row_count))) {
LOG_WARN("fail to generate limit string", K(ret));
} else {
sql_gen.assign_sql_str(select_sql);
}
} else if (parse_tree.type_ == T_SHOW_ERRORS) {
if (OB_FAIL(sql_gen.init(params_.allocator_))) {
LOG_WARN("fail to init sql string generator", K(ret));
} else if (OB_FAIL(sql_gen.gen_select_str(ObShowSqlSet::SHOW_ERRORS_SELECT))) {
LOG_WARN("fail to generate select string", K(ret));
} else if (OB_FAIL(sql_gen.gen_from_str(ObShowSqlSet::SHOW_ERRORS_SUBQUERY, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_WARNING_TNAME))) {
LOG_WARN("fail to generate from string", K(ret));
} else if (OB_FAIL(sql_gen.gen_limit_str(offset, row_count))) {
LOG_WARN("fail to generate limit string", K(ret));
} else {
sql_gen.assign_sql_str(select_sql);
}
} else {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected node type", K(parse_tree.type_));
}
}
} else if (NULL != parse_tree.children_[0] && // show count(*) warnings|errors
T_FUN_COUNT == parse_tree.children_[0]->type_){
if (parse_tree.type_ == T_SHOW_WARNINGS) {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_COUNT_WARNINGS);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_COUNT_WARNINGS, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_WARNING_TNAME);
} else if (parse_tree.type_ == T_SHOW_ERRORS) {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_COUNT_ERRORS);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_COUNT_ERRORS, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_WARNING_TNAME);
} else {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected node type", K(parse_tree.type_));
}
} else {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected child type", K(parse_tree.children_[0]->type_));
}
}
}();
break;
}
case T_SHOW_PARAMETERS: {
uint64_t show_tenant_id = real_tenant_id;
if (OB_UNLIKELY(parse_tree.num_child_ != 2 || nullptr == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_), K(parse_tree.children_));
} else {
show_resv_ctx.stmt_type_ = stmt::T_SHOW_PARAMETERS;
show_resv_ctx.condition_node_ = parse_tree.children_[0];
// tenant=
if (nullptr != parse_tree.children_[1]) {
if (OB_SYS_TENANT_ID != real_tenant_id) {
ret = OB_ERR_NO_PRIVILEGE;
LOG_WARN("non sys tenant", K(real_tenant_id), K(ret));
} else if (OB_UNLIKELY(T_TENANT_NAME != parse_tree.children_[1]->type_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("type is not T_TENANT_NAME", "type",
get_type_name(parse_tree.type_));
} else {
const ParseNode *tenant_node = parse_tree.children_[1];
if (OB_ISNULL(tenant_node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("children should not be null");
} else {
ObString show_tenant_name(tenant_node->children_[0]->str_len_,
tenant_node->children_[0]->str_value_);
if (ObString::make_string("seed") == show_tenant_name) {
params_.show_seed_ = true; // 传递给 stmt
} else if (OB_FAIL(schema_checker_->get_tenant_id(show_tenant_name, show_tenant_id))
|| OB_INVALID_ID == show_tenant_id) {
ret = OB_ERR_INVALID_TENANT_NAME;
LOG_WARN("fail to get tenant id", K(show_tenant_name), K(ret));
} else {
params_.show_tenant_id_ = show_tenant_id;
}
}
}
if (OB_FAIL(ret)) {
break;
}
} // if
if (params_.show_seed_) {
char local_ip[OB_MAX_SERVER_ADDR_SIZE] = "";
if (OB_UNLIKELY(true != GCONF.self_addr_.ip_to_string(local_ip, sizeof(local_ip)))) {
ret = OB_CONVERT_ERROR;
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_PARAMETERS_SEED);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_PARAMETERS_SEED, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_ALL_VIRTUAL_TENANT_PARAMETER_STAT_TNAME, OB_ALL_VIRTUAL_TENANT_PARAMETER_STAT_ORA_TNAME),
local_ip, GCONF.self_addr_.get_port());
}
} else if (OB_SYS_TENANT_ID == show_tenant_id) {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_PARAMETERS);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_PARAMETERS,
REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME),
REAL_NAME(OB_ALL_VIRTUAL_TENANT_PARAMETER_STAT_TNAME, OB_ALL_VIRTUAL_TENANT_PARAMETER_STAT_ORA_TNAME),
show_tenant_id);
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_PARAMETERS);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_PARAMETERS,
REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME),
REAL_NAME(OB_ALL_VIRTUAL_TENANT_PARAMETER_STAT_TNAME, OB_ALL_VIRTUAL_TENANT_PARAMETER_STAT_ORA_TNAME),
show_tenant_id);
}
}
break;
}
case T_SHOW_TABLEGROUPS:{
[&] {
const char *table_name = NULL;
if (OB_UNLIKELY(parse_tree.num_child_ != 1 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_), K(parse_tree.children_));
} else if (OB_FAIL(ObSchemaUtils::get_all_table_name(real_tenant_id, table_name))) {
LOG_WARN("fail to get all table name", K(ret), K(real_tenant_id));
} else {
ObSqlStrGenerator sql_gen;
show_resv_ctx.condition_node_ = parse_tree.children_[0];
show_resv_ctx.stmt_type_ = stmt::T_SHOW_TABLEGROUPS;
uint64_t compat_version = OB_INVALID_VERSION;
if (OB_FAIL(GET_MIN_DATA_VERSION(real_tenant_id, compat_version))) {
LOG_WARN("get min data_version failed", K(ret), K(real_tenant_id));
} else if (compat_version < DATA_VERSION_4_2_0_0) {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_TABLEGROUPS);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_TABLEGROUPS,
REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME),
REAL_NAME(OB_ALL_TABLEGROUP_TNAME, OB_ALL_VIRTUAL_TABLEGROUP_REAL_AGENT_ORA_TNAME),
REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME),
REAL_NAME(table_name, OB_ALL_VIRTUAL_TABLE_REAL_AGENT_ORA_TNAME),
is_oracle_mode ? real_tenant_id : sql_tenant_id,
REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME),
REAL_NAME(OB_ALL_DATABASE_TNAME, OB_ALL_VIRTUAL_DATABASE_REAL_AGENT_ORA_TNAME),
is_oracle_mode ? real_tenant_id : sql_tenant_id,
is_oracle_mode ? real_tenant_id : sql_tenant_id);
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_TABLEGROUPS_V2);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_TABLEGROUPS_V2,
REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME),
REAL_NAME(OB_ALL_TABLEGROUP_TNAME, OB_ALL_VIRTUAL_TABLEGROUP_REAL_AGENT_ORA_TNAME),
REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME),
REAL_NAME(table_name, OB_ALL_VIRTUAL_TABLE_REAL_AGENT_ORA_TNAME),
is_oracle_mode ? real_tenant_id : sql_tenant_id,
REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME),
REAL_NAME(OB_ALL_DATABASE_TNAME, OB_ALL_VIRTUAL_DATABASE_REAL_AGENT_ORA_TNAME),
is_oracle_mode ? real_tenant_id : sql_tenant_id,
is_oracle_mode ? real_tenant_id : sql_tenant_id);
}
}
}();
break;
}
case T_SHOW_STATUS: {
[&] {
if (is_oracle_mode) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "show status in oracle mode is");
} else if (OB_UNLIKELY(parse_tree.num_child_ != 2 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_), K(parse_tree.children_));
} else if (OB_UNLIKELY(NULL == parse_tree.children_[0])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL",
K(ret),
K(parse_tree.children_[0]));
} else {
show_resv_ctx.condition_node_ = parse_tree.children_[1];
show_resv_ctx.stmt_type_ = stmt::T_SHOW_STATUS;
show_resv_ctx.global_scope_ = 1 == parse_tree.children_[0]->value_ ? true : false;
if (true == show_resv_ctx.global_scope_) {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_GLOBAL_STATUS);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_GLOBAL_STATUS, OB_INFORMATION_SCHEMA_NAME, OB_SESSION_STATUS_TNAME);
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_SESSION_STATUS);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_SESSION_STATUS, OB_INFORMATION_SCHEMA_NAME, OB_SESSION_STATUS_TNAME);
}
}
}();
break;
}
case T_SHOW_TENANT: {
[&] {
if (is_oracle_mode) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED,"show tenant in oracle mode is");
} else if (OB_UNLIKELY(parse_tree.num_child_ != 1 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_), K(parse_tree.children_));
} else {
show_resv_ctx.stmt_type_ = stmt::T_SHOW_TENANT;
if (parse_tree.children_[0] != NULL) {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_TENANT_STATUS);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_TENANT_STATUS, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_TENANT_STATUS_TNAME);
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_TENANT);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_TENANT, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_CURRENT_TENANT_TNAME, real_tenant_id);
}
}
}();
break;
}
case T_SHOW_CREATE_TENANT: {
[&] {
if (is_oracle_mode) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "show create tenant in oracle mode is");
} else if (OB_UNLIKELY(parse_tree.num_child_ != 1 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_), K(parse_tree.children_));
} else if (OB_UNLIKELY(NULL == parse_tree.children_[0])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL",
K(ret),
K(parse_tree.children_[0]));
} else {
show_resv_ctx.stmt_type_ = stmt::T_SHOW_CREATE_TENANT;
ObString show_tenant_name;
show_tenant_name.assign_ptr(parse_tree.children_[0]->str_value_,
static_cast<ObString::obstr_size_t>(parse_tree.children_[0]->str_len_));
uint64_t show_tenant_id = OB_INVALID_ID;
if (OB_FAIL(schema_checker_->get_tenant_id(show_tenant_name, show_tenant_id))) {
LOG_WARN("fail to get_tenant_id", K(ret));
} else if ((real_tenant_id != OB_SYS_TENANT_ID && real_tenant_id != show_tenant_id) ||
OB_INVALID_ID == show_tenant_id) {
ret = OB_TENANT_NOT_EXIST;
LOG_USER_ERROR(OB_TENANT_NOT_EXIST, (int)parse_tree.children_[0]->str_len_,
parse_tree.children_[0]->str_value_);
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_CREATE_TENANT);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_CREATE_TENANT, OB_SYS_DATABASE_NAME, OB_TENANT_VIRTUAL_CURRENT_TENANT_TNAME, show_tenant_id);
}
}
}();
break;
}
case T_SHOW_CREATE_TABLEGROUP: {
[&] {
if (OB_UNLIKELY(parse_tree.num_child_ != 1 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_), K(parse_tree.children_));
} else if (OB_UNLIKELY(NULL == parse_tree.children_[0])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL",
K(ret),
K(parse_tree.children_[1]));
} else {
ObString show_tablegroup_name;
uint64_t show_tablegroup_id = OB_INVALID_ID;
show_resv_ctx.stmt_type_ = stmt::T_SHOW_CREATE_TABLEGROUP;
show_tablegroup_name.assign_ptr(parse_tree.children_[0]->str_value_,
static_cast<ObString::obstr_size_t>(parse_tree.children_[0]->str_len_));
const ObTablegroupSchema *tablegroup_schema = NULL;
if (OB_FAIL(schema_checker_->get_tablegroup_schema(real_tenant_id, show_tablegroup_name, tablegroup_schema))) {
if (OB_ISNULL(tablegroup_schema) || OB_INVALID_ID == tablegroup_schema->get_tablegroup_id()) {
ret = OB_TABLEGROUP_NOT_EXIST;
LOG_WARN("tablegroup not exist", K(ret), K(show_tablegroup_name));
} else {
LOG_WARN("fail to get tablegroup_schema", K(ret));
}
} else {
show_tablegroup_id = tablegroup_schema->get_tablegroup_id();
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_CREATE_TABLEGROUP);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_CREATE_TABLEGROUP, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_TENANT_VIRTUAL_SHOW_CREATE_TABLEGROUP_TNAME, OB_TENANT_VIRTUAL_SHOW_CREATE_TABLEGROUP_ORA_TNAME), show_tablegroup_id);
}
}
}();
break;
}
case T_SHOW_ENGINES: {
[&] {
if (is_oracle_mode) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "show engines in oracle mode is");
} else if (OB_UNLIKELY(parse_tree.num_child_ != 0)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_));
} else {
show_resv_ctx.stmt_type_ = stmt::T_SHOW_ENGINES;
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_ENGINES);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_ENGINES, OB_INFORMATION_SCHEMA_NAME, OB_ENGINES_TNAME);
}
}();
break;
}
case T_SHOW_PRIVILEGES: {
[&] {
if (OB_UNLIKELY(parse_tree.num_child_ != 0)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_));
} else {
show_resv_ctx.stmt_type_ = stmt::T_SHOW_PRIVILEGES;
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_PRIVILEGES);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_PRIVILEGES, REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME), REAL_NAME(OB_ALL_VIRTUAL_PRIVILEGE_TNAME, OB_ALL_VIRTUAL_PRIVILEGE_ORA_TNAME));
}
}();
break;
}
case T_SHOW_QUERY_RESPONSE_TIME: {
if (is_oracle_mode) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "show query response time in oracle mode is");
} else if (OB_UNLIKELY(parse_tree.num_child_ != 0)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_));
} else {
show_resv_ctx.stmt_type_ = stmt::T_SHOW_QUERY_RESPONSE_TIME;
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_QUERY_RESPONSE_TIME);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_QUERY_RESPONSE_TIME, OB_SYS_DATABASE_NAME, OB_ALL_VIRTUAL_QUERY_RESPONSE_TIME_TNAME, real_tenant_id);
}
break;
}
case T_SHOW_RECYCLEBIN: {
[&] {
if (OB_UNLIKELY(parse_tree.num_child_ != 0)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_));
} else {
show_resv_ctx.stmt_type_ = stmt::T_SHOW_RECYCLEBIN;
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_RECYCLEBIN);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_RECYCLEBIN,
REAL_NAME(OB_SYS_DATABASE_NAME, OB_ORA_SYS_SCHEMA_NAME),
REAL_NAME(OB_ALL_RECYCLEBIN_TNAME, OB_ALL_VIRTUAL_RECYCLEBIN_REAL_AGENT_ORA_TNAME));
}
}();
break;
}
case T_SHOW_SEQUENCES: {
if (is_oracle_mode) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "show sequence in oracle mode is");
} else if (OB_UNLIKELY(parse_tree.num_child_ != 2 || NULL == parse_tree.children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_), K(parse_tree.children_));
} else {
show_resv_ctx.stmt_type_ = stmt::T_SHOW_SEQUENCES;
show_resv_ctx.condition_node_ = parse_tree.children_[0];
ParseNode *condition_node = show_resv_ctx.condition_node_;
ObString show_db_name;
uint64_t show_db_id = OB_INVALID_ID;
if (OB_FAIL(get_database_info(parse_tree.children_[1],
database_name,
real_tenant_id,
show_resv_ctx,
show_db_id))) {
LOG_WARN("fail to get database info", K(ret));
} else if (OB_UNLIKELY(OB_INVALID_ID == show_db_id)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("database id is invalid", K(ret), K(show_db_id));
} else {
show_db_name = show_resv_ctx.show_database_name_;
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 {
LOG_WARN("fail to check priv", K(ret));
}
} else {
if (NULL != condition_node && T_LIKE_CLAUSE == condition_node->type_) {
if (OB_UNLIKELY(condition_node->num_child_ != 2
|| NULL == condition_node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid like parse node",
K(ret),
K(condition_node->num_child_),
K(condition_node->children_));
} else if (OB_UNLIKELY(NULL == condition_node->children_[0]
|| NULL == condition_node->children_[1])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid like parse node",
K(ret),
K(condition_node->num_child_),
K(condition_node->children_[0]),
K(condition_node->children_[1]));
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_SEQUENCES_LIKE,
show_resv_ctx.show_database_name_.length(),
show_resv_ctx.show_database_name_.ptr(),
static_cast<ObString::obstr_size_t>(condition_node->children_[0]->str_len_),//cast int64_t to obstr_size_t
condition_node->children_[0]->str_value_);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_SEQUENCES_LIKE, OB_SYS_DATABASE_NAME, OB_ALL_SEQUENCE_OBJECT_TNAME, show_db_id);
}
} else {
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_SEQUENCES, show_resv_ctx.show_database_name_.length(),
show_resv_ctx.show_database_name_.ptr());
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_SEQUENCES, OB_SYS_DATABASE_NAME, OB_ALL_SEQUENCE_OBJECT_TNAME, show_db_id);
}
}
//change where condition :Tables_in_xxx=>table_name
if (OB_SUCCESS == ret && NULL != condition_node && T_WHERE_CLAUSE == condition_node->type_) {
char *column_name = NULL;
int64_t tmp_pos = 0;
if (OB_FAIL(NULL == (column_name = static_cast<char *>(params_.allocator_->alloc(OB_MAX_COLUMN_NAME_BUF_LENGTH))))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("failed to alloc column name buf", K(column_name));
} else if (OB_FAIL(databuff_printf(column_name,
OB_MAX_COLUMN_NAME_BUF_LENGTH,
tmp_pos,
"sequence_in_%.*s",
show_resv_ctx.show_database_name_.length(),
show_resv_ctx.show_database_name_.ptr()))) {
LOG_WARN("fail to add database name", K(show_resv_ctx.show_database_name_.ptr()));
break;
} else if (FALSE_IT(show_resv_ctx.column_name_ = ObString::make_string(column_name))){
//won't be here
} else if(OB_FAIL(replace_where_clause(condition_node->children_[0], show_resv_ctx))) {
LOG_WARN("fail to replace where clause", K(condition_node->children_[0]));
break;
}
}
}
}
break;
}
case T_SHOW_RESTORE_PREVIEW: {
if (OB_UNLIKELY(parse_tree.num_child_ != 0)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(parse_tree.num_child_));
} else if (!is_sys_tenant(real_tenant_id)) {
ret = OB_OP_NOT_ALLOW;
LOG_WARN("the tenant has no priv to show restore preview", K(ret), K(real_tenant_id));
} else {
show_resv_ctx.stmt_type_ = stmt::T_SHOW_RESTORE_PREVIEW;
GEN_SQL_STEP_1(ObShowSqlSet::SHOW_RESTORE_PREVIEW);
GEN_SQL_STEP_2(ObShowSqlSet::SHOW_RESTORE_PREVIEW,
OB_SYS_DATABASE_NAME,
OB_TENANT_VIRTUAL_SHOW_RESTORE_PREVIEW_TNAME);
}
break;
}
default:
/* won't be here */
ret = OB_NOT_IMPLEMENT;
LOG_WARN("not implement type", K(parse_tree.type_));
break;
}
if (OB_SUCC(ret)) {
if (OB_FAIL(parse_and_resolve_select_sql(select_sql))) {
LOG_WARN("fail to parse and resolve select sql", K(ret), K(select_sql));
} else if (OB_FAIL(resolve_like_or_where_clause(show_resv_ctx))) {
LOG_WARN("fail to resolve like or where clause", K(ret), K(show_resv_ctx), K(select_sql));
}
}
}
if (OB_SUCC(ret) && synonym_checker.has_synonym()) {
if (OB_FAIL(add_synonym_obj_id(synonym_checker, false/* error_with_exist */))) {
LOG_WARN("add_synonym_obj_id failed", K(ret), K(synonym_checker.get_synonym_ids()));
}
}
if (OB_LIKELY(OB_SUCCESS == ret && NULL != stmt_)) {
if (OB_UNLIKELY(stmt::T_SELECT != stmt_->get_stmt_type())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected stmt type", K(stmt_->get_stmt_type()));
} else {
ObSelectStmt *select_stmt = static_cast<ObSelectStmt*>(stmt_);
select_stmt->set_is_from_show_stmt(true);
if (OB_NOT_NULL(select_stmt->get_query_ctx())) {
select_stmt->get_query_ctx()->set_literal_stmt_type(show_resv_ctx.stmt_type_);
}
if (OB_FAIL(process_select_type(select_stmt, show_resv_ctx.stmt_type_, parse_tree))) {
LOG_WARN("fail to process select type", K(ret), K(show_resv_ctx));
} else if (OB_FAIL(select_stmt->formalize_stmt(session_info_))) {
LOG_WARN("pull select stmt all expr relation ids failed", K(ret));
}
}
}
return ret;
}
int ObShowResolver::get_database_info(const ParseNode *database_node,
const ObString &database_name,
uint64_t real_tenant_id,
ObShowResolverContext &show_resv_ctx,
uint64_t &show_db_id)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(schema_checker_)) {
ret = OB_NOT_INIT;
LOG_WARN("some data member is not init", K(ret), K(schema_checker_));
} else {
if (NULL == database_node) {
if (OB_UNLIKELY(database_name.empty())) {
ret = OB_ERR_NO_DB_SELECTED;
LOG_WARN("no database selected");
} else {
show_resv_ctx.show_database_name_ = database_name;
if (OB_FAIL(schema_checker_->get_database_id(real_tenant_id, database_name, show_db_id))) {
LOG_WARN("fail to get database_id", K(ret), K(database_name), K(real_tenant_id));
}
}
} else {
ObString show_db_name;
if (OB_UNLIKELY(database_node->num_child_ != 1 || NULL == database_node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(database_node->num_child_), K(database_node->children_));
} else if (OB_UNLIKELY(NULL == database_node->children_[0])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("show from database node is NULL", K(ret));
} else if (OB_FAIL(resolve_show_from_database(*database_node->children_[0],
real_tenant_id,
show_db_id,
show_resv_ctx.show_database_name_))) {
LOG_WARN("fail to resolve show from database", K(ret), K(real_tenant_id));
} else {/*do nothing*/}
}
}
return ret;
}
//判断各个show语句是否会影响found_row的结果
int ObShowResolver::process_select_type(ObSelectStmt *select_stmt,
stmt::StmtType stmt_type,
const ParseNode &parse_tree)
{
//注释掉的代码不要删掉,等对应功能实现以后,还要加回来的 by rongxuan.lc
//并不是完全枚举,其中去掉里一些OB应该不会实现的功能,比如:show master status; show open tables
//具体可以参照mysql_test/t/found_rows_show_stmt.test中被注释掉的case
int ret = OB_SUCCESS;
if ((stmt_type == stmt::T_SHOW_ERRORS
|| stmt_type == stmt::T_SHOW_WARNINGS)
&& parse_tree.children_[0] != NULL
&& T_FUN_COUNT == parse_tree.children_[0]->type_) {
//select count(*) error/warn 特殊处理
select_stmt->set_select_type(AFFECT_FOUND_ROWS);
} else if (stmt_type == stmt::T_SHOW_CREATE_TABLE
//|| stmt_type == stmt::T_SHOW_CREATE_TRIGGER
|| stmt_type == stmt::T_SHOW_CREATE_DATABASE
|| stmt_type == stmt::T_SHOW_CREATE_TABLEGROUP
//|| stmt_type == stmt::T_SHOW_CREATE_EVENT
//|| stmt_type == stmt::T_SHOW_CREATE_FUNCIONT
|| stmt_type == stmt::T_SHOW_CREATE_VIEW
|| stmt_type == stmt::T_SHOW_ERRORS
|| stmt_type == stmt::T_SHOW_GRANTS
//|| stmt_type == stmt::T_SHOW_PRIVILEGES
|| stmt_type == stmt::T_SHOW_PROCESSLIST
//|| stmt_type == stmt::T_SHOW_PROFILES
|| stmt_type == stmt::T_SHOW_WARNINGS) {
select_stmt->set_select_type(NOT_AFFECT_FOUND_ROWS);
} else {
select_stmt->set_select_type(AFFECT_FOUND_ROWS);
}
return ret;
}
int ObShowResolver::check_desc_priv_if_ness(
uint64_t real_tenant_id,
const ObTableSchema *table_schema,
const ObString &database_name,
bool is_sys_view)
{
int ret = OB_SUCCESS;
bool should_check_priv = false;
CK (NULL != table_schema);
if (lib::is_oracle_mode()) {
const ObString table_name = table_schema->get_table_name_str();
/* 增加sys_view的赋值。用户指定数据库名,is_sys_view未赋值 */
if (false == is_sys_view) {
if (table_schema->is_sys_view()) {
is_sys_view = true;
} else if (ObSQLUtils::is_oracle_sys_view(table_name)) {
is_sys_view = true;
}
}
/* 只有dba_开头的系统视图需要check权限,其他系统视图不需要 */
if (is_sys_view) {
if (table_name.prefix_match("DBA_")) {
should_check_priv = true;
}
} else {
should_check_priv = true;
}
if (should_check_priv) {
bool accessible = false;
const ObUserInfo *user_info = NULL;
OZ (schema_checker_->get_user_info(real_tenant_id, session_info_->get_priv_user_id(), user_info));
if (OB_SUCC(ret)) {
if (ObOraPrivCheck::user_is_owner(user_info->get_user_name(), database_name)) {
accessible = true;
} else {
OZ (schema_checker_->check_access_to_obj(real_tenant_id,
session_info_->get_priv_user_id(),
table_schema->get_table_id(),
database_name,
stmt::T_SHOW_COLUMNS,
session_info_->get_enable_role_array(),
accessible,
is_sys_view));
}
if (OB_SUCC(ret) && false == accessible) {
ObSqlString full_obj_name;
OZ (full_obj_name.append_fmt("%.*s.%.*s", database_name.length(),
database_name.ptr(),
table_name.length(),
table_name.ptr()));
if (OB_SUCC(ret)) {
ret = OB_ERR_OBJECT_STRING_DOES_NOT_EXIST;
LOG_USER_ERROR(OB_ERR_OBJECT_STRING_DOES_NOT_EXIST, static_cast<int>(full_obj_name.length()),
full_obj_name.ptr());
LOG_WARN("No privielege", K(ret), K(table_schema->get_table_name()));
}
}
}
}
}
return ret;
}
int ObShowResolver::resolve_show_from_table(const ParseNode *from_table_node,
const ParseNode *from_database_clause_node,
bool is_database_unselected,
ObItemType node_type,
uint64_t real_tenant_id,
ObString &show_database_name,
uint64_t &show_database_id,
ObString &show_table_name,
uint64_t &show_table_id,
bool &is_view,
ObSynonymChecker &synonym_checker)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(NULL == schema_checker_)) {
ret = OB_ERR_SCHEMA_UNSET;
LOG_WARN("some data member is not init", K(ret), K(schema_checker_));
} else if (OB_UNLIKELY(NULL == session_info_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("session info is null", K(ret));
} else if (OB_UNLIKELY(T_RELATION_FACTOR != from_table_node->type_
|| from_table_node->num_child_ < 2
|| NULL == from_table_node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is invalid",
K(ret),
K(from_table_node->type_),
K(from_table_node->num_child_),
K(from_table_node->children_));
} else if (from_table_node->num_child_ > 2 && OB_NOT_NULL(from_table_node->children_[2])) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "desc link table is");
} else if (OB_UNLIKELY(NULL == from_table_node->children_[1])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL",
K(ret),
K(from_table_node->children_[1]));
} else {
bool is_sys_view = false;
const ObTableSchema *table_schema = NULL;
if (NULL == from_database_clause_node) {
if(OB_UNLIKELY(is_database_unselected && NULL == from_table_node->children_[0])) {
ret = OB_ERR_NO_DB_SELECTED;
LOG_WARN("no database selected");
} else { // database从table子句中取
ObString synonym_name;
ObString synonym_db_name;
if (OB_FAIL(resolve_table_relation_factor_normal(from_table_node,
real_tenant_id,
show_database_id,
show_table_name,
synonym_name,
synonym_db_name,
show_database_name,
synonym_checker))) {
if (OB_TABLE_NOT_EXIST == ret) {
// check inner sys view
bool use_sys_tenant = false;
int tmp_ret = OB_SUCCESS;
if (OB_SUCCESS != (tmp_ret = inner_resolve_sys_view(from_table_node, show_database_id, show_table_name, show_database_name, use_sys_tenant))) {
LOG_WARN("fail to resolve sys view", K(tmp_ret));
} else {
ret = OB_SUCCESS;
}
if (OB_SUCC(ret)) {
is_sys_view = true;
// resolve success
} else if (is_information_schema_database_id(show_database_id)) {
ret = OB_ERR_UNKNOWN_TABLE;
LOG_USER_ERROR(OB_ERR_UNKNOWN_TABLE, show_table_name.length(), show_table_name.ptr(),
show_database_name.length(), show_database_name.ptr());
} else {
/* 兼容oracle错误码 */
if (lib::is_oracle_mode() && node_type == T_SHOW_COLUMNS) {
ObSqlString full_obj_name;
ret = OB_SUCCESS;
OZ (full_obj_name.append_fmt("%.*s.%.*s",
show_database_name.length(),
show_database_name.ptr(),
show_table_name.length(),
show_table_name.ptr()));
if (OB_SUCC(ret)) {
ret = OB_ERR_OBJECT_STRING_DOES_NOT_EXIST;
LOG_USER_ERROR(OB_ERR_OBJECT_STRING_DOES_NOT_EXIST,
static_cast<int>(full_obj_name.length()),
full_obj_name.ptr());
LOG_WARN("table not exists", K(ret), K(show_table_name));
}
} else {
LOG_USER_ERROR(OB_TABLE_NOT_EXIST, to_cstring(show_database_name), to_cstring(show_table_name));
}
}
} else {
if (lib::is_oracle_mode() && node_type == T_SHOW_COLUMNS) {
ObSqlString full_obj_name;
ret = OB_SUCCESS;
OZ (full_obj_name.append_fmt("%.*s.%.*s",
show_database_name.length(),
show_database_name.ptr(),
show_table_name.length(),
show_table_name.ptr()));
if (OB_SUCC(ret)) {
ret = OB_ERR_OBJECT_STRING_DOES_NOT_EXIST;
LOG_USER_ERROR(OB_ERR_OBJECT_STRING_DOES_NOT_EXIST,
static_cast<int>(full_obj_name.length()),
full_obj_name.ptr());
LOG_WARN("table not exists", K(ret), K(show_table_name));
}
} else {
LOG_WARN("fail to resolve table name", K(ret));
}
}
}
}
} else if (NULL == from_database_clause_node->children_[0]) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("from_database_clause_node->children_[0] is NULL", K(ret));
} else {
// database从from database子句中取
if (OB_UNLIKELY(T_FROM_LIST != from_database_clause_node->type_
|| from_database_clause_node->num_child_ != 1
|| NULL == from_table_node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is invalid",
K(ret),
K(from_database_clause_node->type_),
K(from_database_clause_node->num_child_),
K(from_database_clause_node->children_));
} else if (OB_UNLIKELY(NULL == from_database_clause_node->children_[0])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL",
K(ret),
K(from_database_clause_node->children_[0]));
} else {
ParseNode *relation_node = from_table_node->children_[1];
show_table_name.assign_ptr(const_cast<char *>(relation_node->str_value_),
static_cast<int32_t>(relation_node->str_len_));
if (show_table_name.empty()) {
ret = OB_WRONG_TABLE_NAME;
LOG_WARN("table name is empty", K(ret));
} else if (OB_FAIL(resolve_show_from_database(
*from_database_clause_node->children_[0],
real_tenant_id,
show_database_id,
show_database_name))) {
LOG_WARN("fail to resolve show from database",
K(ret), K(real_tenant_id));
}
}
}
const bool is_index = false;
uint64_t org_session_id = OB_INVALID_ID;
//bug16913178, 设置 session id = 0以便返回view, 否则临时表会返回
if (T_SHOW_CREATE_VIEW == node_type
&& OB_NOT_NULL(schema_checker_->get_schema_mgr())) {
org_session_id = schema_checker_->get_schema_mgr()->get_session_id();
schema_checker_->get_schema_mgr()->set_session_id(0);
}
if (OB_FAIL(ret)) {
// do nothing
} else if (OB_FAIL(schema_checker_->get_table_schema(real_tenant_id,
show_database_id,
show_table_name,
is_index,
false, /*cte_table_fisrt false*/
false/*is_hidden*/,
table_schema))) {
LOG_WARN("get table schema failed", K(ret),
K(real_tenant_id), K(show_database_id), K(show_table_name));
} else if (OB_UNLIKELY(NULL == table_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table schema from schema checker is NULL", K(ret), K(table_schema));
} else if (T_SHOW_CREATE_VIEW == node_type &&
!table_schema->is_view_table()) {
ret = OB_ERR_WRONG_OBJECT;
LOG_USER_ERROR(OB_ERR_WRONG_OBJECT, to_cstring(show_database_name), to_cstring(show_table_name), "VIEW");
} else {
show_table_id = table_schema->get_table_id();
is_view = table_schema->is_view_table() ? true : false;
OZ (check_desc_priv_if_ness(real_tenant_id, table_schema, show_database_name, is_sys_view));
}
if (OB_INVALID_ID != org_session_id) {
schema_checker_->get_schema_mgr()->set_session_id(org_session_id);
}
}
return ret;
}
int ObShowResolver::resolve_show_from_database(const ParseNode &from_db_node,
uint64_t real_tenant_id,
uint64_t &show_database_id,
ObString &show_database_name)
{
// resolve clause for database name
int ret = OB_SUCCESS;
if (OB_FAIL(resolve_database_factor(&from_db_node,
real_tenant_id,
show_database_id,
show_database_name))) {
if (OB_ERR_BAD_DATABASE == ret) {
LOG_USER_ERROR(OB_ERR_BAD_DATABASE, show_database_name.length(), show_database_name.ptr());
} else {
LOG_WARN("fail to resolve database name", K(ret));
}
}
return ret;
}
int ObShowResolver::resolve_show_from_routine(const ParseNode *from_routine_node,
const ParseNode *from_database_clause_node,
bool is_database_unselected,
ObItemType node_type,
uint64_t real_tenant_id,
ObString &show_database_name,
uint64_t &show_database_id,
ObString &show_routine_name,
uint64_t &show_routine_id,
int64_t &routine_type)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(NULL == schema_checker_)) {
ret = OB_ERR_SCHEMA_UNSET;
LOG_WARN("some data member is not init", K(ret), K(schema_checker_));
} else if (OB_UNLIKELY(T_RELATION_FACTOR != from_routine_node->type_
// add opt dblink_node
|| from_routine_node->num_child_ < 2
|| NULL == from_routine_node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is invalid",
K(ret),
K(from_routine_node->type_),
K(from_routine_node->num_child_),
K(from_routine_node->children_));
} else if (OB_UNLIKELY(NULL == from_routine_node->children_[1])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL", K(ret), K(from_routine_node->children_[1]));
} else {
const ObRoutineInfo *routine_info = NULL;
if (NULL == from_database_clause_node) {
if(OB_UNLIKELY(is_database_unselected && NULL == from_routine_node->children_[0])) {
ret = OB_ERR_NO_DB_SELECTED;
LOG_WARN("no database selected");
} else { // database从procedure子句中取
show_routine_name.assign_ptr(from_routine_node->children_[1]->str_value_, static_cast<int32_t>(from_routine_node->children_[1]->str_len_));
const ParseNode *db_node = NULL;
if (NULL == (db_node = from_routine_node->children_[0])) {
show_database_name = session_info_->get_database_name();
} else if (OB_UNLIKELY(db_node->type_ != T_IDENT)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("Invalid node type", K(ret));
} else {
show_database_name.assign_ptr(db_node->str_value_, static_cast<int32_t>(db_node->str_len_));
}
if (OB_SUCC(ret) && OB_FAIL(schema_checker_->get_database_id(real_tenant_id, show_database_name, show_database_id))) {
LOG_WARN("failed to get procedure id", K(real_tenant_id), K(show_database_name), K(ret));
} else { /*do nothing*/ }
}
} else if (NULL == from_database_clause_node->children_[0]) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("from_database_clause_node->children_[0] is NULL", K(ret));
} else {
// database从from database子句中取
if (OB_UNLIKELY(T_FROM_LIST != from_database_clause_node->type_
|| from_database_clause_node->num_child_ != 1
|| NULL == from_routine_node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is invalid",
K(ret),
K(from_database_clause_node->type_),
K(from_database_clause_node->num_child_),
K(from_database_clause_node->children_));
} else if (OB_UNLIKELY(NULL == from_database_clause_node->children_[0])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL", K(ret), K(from_database_clause_node->children_[0]));
} else {
ParseNode *routine_node = from_routine_node->children_[1];
show_routine_name.assign_ptr(const_cast<char *>(routine_node->str_value_),
static_cast<int32_t>(routine_node->str_len_));
if (show_routine_name.empty()) {
ret = OB_WRONG_TABLE_NAME;
LOG_WARN("table name is empty", K(ret));
} else if (OB_FAIL(resolve_show_from_database(
*from_database_clause_node->children_[0],
real_tenant_id,
show_database_id,
show_database_name))) {
LOG_WARN("fail to resolve show from database", K(ret), K(real_tenant_id));
}
}
}
if (OB_FAIL(ret)) {
// do nothing
} else {
if (T_SHOW_CREATE_PROCEDURE == node_type) {
if (OB_FAIL(schema_checker_->get_standalone_procedure_info(real_tenant_id,
show_database_name, show_routine_name, routine_info))) {
LOG_WARN("get procedure info failed", K(ret),
K(real_tenant_id), K(show_database_name), K(show_routine_name));
}
} else {
if (OB_FAIL(schema_checker_->get_standalone_function_info(real_tenant_id,
show_database_name, show_routine_name, routine_info))) {
LOG_WARN("get function info failed", K(ret),
K(real_tenant_id), K(show_database_name), K(show_routine_name));
}
}
}
if (OB_SUCC(ret)) {
if (OB_UNLIKELY(NULL == routine_info)) {
ret = OB_ERR_SP_DOES_NOT_EXIST;
LOG_WARN("procudure info from schema checker is NULL", K(ret), K(routine_info));
} else {
show_routine_id = routine_info->get_routine_id();
routine_type = routine_info->get_routine_type();
}
}
}
return ret;
}
int ObShowResolver::resolve_show_from_trigger(const ParseNode *from_tg_node,
const ParseNode *from_database_clause_node,
bool is_database_unselected,
uint64_t real_tenant_id,
ObString &show_database_name,
uint64_t &show_database_id,
ObString &show_tg_name,
uint64_t &show_tg_id)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(NULL == schema_checker_)) {
ret = OB_ERR_SCHEMA_UNSET;
LOG_WARN("some data member is not init", K(ret), K(schema_checker_));
} else if (OB_UNLIKELY(T_RELATION_FACTOR != from_tg_node->type_
|| from_tg_node->num_child_ < 2
|| NULL == from_tg_node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is invalid", K(ret), K(from_tg_node->type_),
K(from_tg_node->num_child_), K(from_tg_node->children_));
} else if (OB_UNLIKELY(NULL == from_tg_node->children_[1])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL", K(ret), K(from_tg_node->children_[1]));
} else {
const ObTriggerInfo *tg_info = NULL;
if (NULL == from_database_clause_node) {
if (OB_UNLIKELY(is_database_unselected && NULL == from_tg_node->children_[0])) {
ret = OB_ERR_NO_DB_SELECTED;
LOG_WARN("no database selected", K(ret));
} else {
const ParseNode *db_node = NULL;
show_tg_name.assign_ptr(from_tg_node->children_[1]->str_value_,
static_cast<int32_t>(from_tg_node->children_[1]->str_len_));
if (NULL == (db_node = from_tg_node->children_[0])) {
show_database_name = session_info_->get_database_name();
} else if (OB_UNLIKELY(db_node->type_ != T_IDENT)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("Invalid node type", K(ret));
} else {
show_database_name.assign_ptr(db_node->str_value_,
static_cast<int32_t>(db_node->str_len_));
}
OZ (schema_checker_->get_database_id(real_tenant_id, show_database_name, show_database_id),
real_tenant_id, show_database_name, show_database_id);
}
} else if (NULL == from_database_clause_node->children_[0]) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("from database clause node is NULL", K(ret));
} else {
// database从from database子句中取
if (OB_UNLIKELY(T_FROM_LIST != from_database_clause_node->type_
|| from_database_clause_node->num_child_ != 1
|| NULL == from_tg_node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is invalid",
K(ret),
K(from_database_clause_node->type_),
K(from_database_clause_node->num_child_),
K(from_database_clause_node->children_));
} else if (OB_UNLIKELY(NULL == from_database_clause_node->children_[0])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL", K(ret), K(from_database_clause_node->children_[0]));
} else {
ParseNode *tg_node = from_tg_node->children_[1];
show_tg_name.assign_ptr(const_cast<char *>(tg_node->str_value_),
static_cast<int32_t>(tg_node->str_len_));
OZ (resolve_show_from_database(*from_database_clause_node->children_[0],
real_tenant_id, show_database_id, show_database_name),
real_tenant_id);
}
}
OZ (schema_checker_->get_trigger_info(real_tenant_id, show_database_name,
show_tg_name, tg_info),
real_tenant_id, show_database_name, show_tg_name);
OV (OB_NOT_NULL(tg_info), OB_ERR_TRIGGER_NOT_EXIST);
OX (show_tg_id = tg_info->get_trigger_id());
}
return ret;
}
int ObShowResolver::parse_and_resolve_select_sql(const ObString &select_sql)
{
int ret = OB_SUCCESS;
// 1. parse and resolve view defination
if (OB_ISNULL(session_info_) || OB_ISNULL(params_.allocator_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("data member is not init", K(ret), K(session_info_), K(params_.allocator_));
} else {
ParseResult select_result;
ObParser parser(*params_.allocator_, session_info_->get_sql_mode());
if (OB_FAIL(parser.parse(select_sql, select_result))) {
LOG_WARN("parse select sql failed", K(select_sql), K(ret));
} else {
// use alias to make all columns number continued
if (OB_ISNULL(select_result.result_tree_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("result tree is NULL", K(ret));
} else if (OB_UNLIKELY(select_result.result_tree_->num_child_ != 1
|| NULL == select_result.result_tree_->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("result tree is invalid",
K(ret), K(select_result.result_tree_->num_child_), K(select_result.result_tree_->children_));
} else if (OB_UNLIKELY(NULL == select_result.result_tree_->children_[0])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("result tree is invalid", K(ret), "child ptr", select_result.result_tree_->children_[0]);
} else {
ParseNode *select_stmt_node = select_result.result_tree_->children_[0];
if (OB_FAIL(ObSelectResolver::resolve(*select_stmt_node))) {
LOG_WARN("resolve select in view definition failed", K(ret), K(select_stmt_node));
}
}
}
}
return ret;
}
int ObShowResolver::resolve_like_or_where_clause(ObShowResolverContext &ctx)
{
int ret = OB_SUCCESS;
const ParseNode *parse_tree = ctx.parse_tree_;
ParseNode *condition_node = ctx.condition_node_;
ObDMLStmt *stmt = get_stmt();
if (OB_ISNULL(ctx.parse_tree_) || OB_ISNULL(stmt) || OB_ISNULL(allocator_) || OB_ISNULL(params_.expr_factory_)) {
ret = OB_NOT_INIT;
LOG_WARN("data member is not init", K(ret), K(ctx.parse_tree_), K(stmt), K_(params_.expr_factory));
} else if (NULL == condition_node
|| (parse_tree->type_ != T_SHOW_TABLES
&& parse_tree->type_ != T_SHOW_DATABASES
&& parse_tree->type_ != T_SHOW_VARIABLES
&& parse_tree->type_ != T_SHOW_CHARSET
&& parse_tree->type_ != T_SHOW_COLLATION
&& parse_tree->type_ != T_SHOW_TRACE
&& parse_tree->type_ != T_SHOW_COLUMNS
&& parse_tree->type_ != T_SHOW_TABLE_STATUS
&& parse_tree->type_ != T_SHOW_SERVER_STATUS
&& parse_tree->type_ != T_SHOW_INDEXES
&& parse_tree->type_ != T_SHOW_PARAMETERS
&& parse_tree->type_ != T_SHOW_STATUS
&& parse_tree->type_ != T_SHOW_TABLEGROUPS
&& parse_tree->type_ != T_SHOW_PROCEDURE_STATUS
&& parse_tree->type_ != T_SHOW_FUNCTION_STATUS
&& parse_tree->type_ != T_SHOW_TRIGGERS
&& parse_tree->type_ != T_SHOW_SEQUENCES)) {
// do nothing
} else {
// Like or Where clause
if (T_LIKE_CLAUSE == condition_node->type_) {
// like clause
if (OB_UNLIKELY(condition_node->num_child_ != 2 || NULL == condition_node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(condition_node->num_child_), K(condition_node->children_));
} else if (OB_UNLIKELY(NULL == condition_node->children_[0]
|| NULL == condition_node->children_[1])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree child is NULL",
K(ret),
K(condition_node->children_[0]),
K(condition_node->children_[1]));
} else if (OB_UNLIKELY((T_VARCHAR != condition_node->children_[0]->type_
&& T_CHAR != condition_node->children_[0]->type_)
|| (T_VARCHAR != condition_node->children_[1]->type_
&& T_CHAR != condition_node->children_[1]->type_))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse node type is unexpected",
K(ret),
K(condition_node->children_[0]->type_),
K(condition_node->children_[1]->type_));
} else {
ObString like_pattern;
ObString like_escape;
like_pattern.assign_ptr(static_cast<const char *>(condition_node->children_[0]->str_value_),
static_cast<int32_t>((condition_node->children_[0]->str_len_)));
like_escape.assign_ptr(static_cast<const char *>(condition_node->children_[1]->str_value_),
static_cast<int32_t>(condition_node->children_[1]->str_len_));
ObRawExpr *ref_expr = NULL;
ObConstRawExpr *like_pat_expr = NULL;
ObConstRawExpr *like_es_expr = NULL;
ObOpRawExpr *op_expr = NULL;
if (like_pattern.length() <= 0) {
// stmt has no like pattern, do nothing
} else {
ObString col_name;
ObString alias_name;
ObQualifiedName q_name;
q_name.database_name_ = ObString::make_string("");
if (lib::is_oracle_mode()) {
// alias name and column name must be upper
size_t size = 0;
if (OB_FAIL(ob_write_string(*params_.allocator_, ObString::make_string(ObShowSqlSet::SUBQERY_ALIAS), alias_name))) {
LOG_WARN("write alias name failed", K(ret));
} else if (OB_FAIL(ob_write_string(*params_.allocator_, ctx.like_column_, col_name))) {
LOG_WARN("write column name failed", K(ret));
} else {
if (!col_name.empty()) {
size = ObCharset::caseup(ObCollationType::CS_TYPE_UTF8MB4_BIN, col_name.ptr(), col_name.length(), col_name.ptr(), col_name.length());
col_name.set_length(static_cast<int32_t>(size));
}
if (!alias_name.empty()) {
size = ObCharset::caseup(ObCollationType::CS_TYPE_UTF8MB4_BIN, alias_name.ptr(), alias_name.length(), alias_name.ptr(), alias_name.length());
alias_name.set_length(static_cast<int32_t>(size));
}
}
} else {
alias_name = ObString::make_string(ObShowSqlSet::SUBQERY_ALIAS);
col_name = ctx.like_column_;
}
q_name.tbl_name_ = alias_name;
q_name.col_name_ = col_name;
if (OB_FAIL(resolve_column_ref_expr(q_name, ref_expr))) {
LOG_WARN("resolve column ref expr failed", K(q_name));
} else if (OB_ISNULL(ref_expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("column expr is null");
} else if (OB_FAIL(ObRawExprUtils::build_const_string_expr(*params_.expr_factory_,
ObVarcharType,
like_pattern,
ObCharset::get_default_collation(ObCharset::get_default_charset()),
like_pat_expr))) {
LOG_WARN("fail to create string raw expr", K(ret), K(like_pattern));
} else if (OB_FAIL(ObRawExprUtils::build_const_string_expr(*params_.expr_factory_,
ObVarcharType,
like_escape,
ObCharset::get_default_collation(ObCharset::get_default_charset()),
like_es_expr))) {
LOG_WARN("fail to create string raw expr", K(ret), K(like_escape));
} else if (OB_FAIL(params_.expr_factory_->create_raw_expr(T_OP_LIKE, op_expr))) {
LOG_WARN("create raw expr failed", K(ret));
} else if (OB_ISNULL(op_expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("op expr is null");
} else {
op_expr->set_param_exprs(ref_expr, like_pat_expr, like_es_expr);
if (OB_FAIL(op_expr->formalize(session_info_))) {
LOG_WARN("fail to formalize expression", K(ret), K(op_expr));
} else if (OB_FAIL(stmt->add_condition_expr(op_expr))) {
LOG_WARN("fail to add condition expression", K(ret), K(op_expr));
}
}
}
}
} else if (T_WHERE_CLAUSE == condition_node->type_) {
// where clause
if (OB_FAIL(ObDMLResolver::resolve_where_clause(condition_node))) {
LOG_WARN("resolve where clause failed", K(ret));
}
} else {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid condition type", K(ret), K(get_type_name(condition_node->type_)));
}
}
return ret;
}
int ObShowResolver::replace_where_clause(ParseNode* node, const ObShowResolverContext &show_resv_ctx)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(node)) {
ret = OB_ERR_NULL_VALUE;
LOG_WARN("expr node is null");
} else {
switch (node->type_) {
case T_NULL:
case T_INT:
case T_FLOAT:
case T_DOUBLE:
case T_YEAR:
case T_DATE:
case T_TIME:
case T_DATETIME:
case T_TIMESTAMP:
case T_TIMESTAMP_TZ:
case T_TIMESTAMP_LTZ:
case T_TIMESTAMP_NANO:
case T_HEX_STRING:
case T_BOOL:
case T_NUMBER:
case T_NUMBER_FLOAT:
case T_QUESTIONMARK:
case T_SYSTEM_VARIABLE:
case T_DEFAULT_NULL:
case T_VARCHAR:
case T_RAW:
case T_INTERVAL_YM:
case T_INTERVAL_DS:
case T_NVARCHAR2:
case T_NCHAR:
case T_UROWID:
case T_LOB:
case T_JSON:
case T_GEOMETRY:
case T_IEEE754_NAN:
case T_IEEE754_INFINITE: {
break;//do nothing
}
case T_COLUMN_REF: {
//expr has column == tables_in_xxx,must be changed to the real column name :table_name
if (ObCharset::case_insensitive_equal(ObString(node->str_len_, node->str_value_),
show_resv_ctx.column_name_)) {
node->str_value_ = "table_name";
node->str_len_ = strlen("table_name");
}
if (OB_UNLIKELY(node->num_child_ != 3 || NULL == node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(node->num_child_), K(node->children_));
} else if (OB_UNLIKELY(NULL == node->children_[2])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL", K(ret), K(node->children_[2]));
} else {
if (ObCharset::case_insensitive_equal(
ObString(node->children_[2]->str_len_, node->children_[2]->str_value_),
show_resv_ctx.column_name_)) {
node->children_[2]->str_value_ = "table_name";
node->children_[2]->str_len_ = strlen("table_name");
}
}
break;
}
case T_OBJ_ACCESS_REF: {
if (OB_UNLIKELY(node->num_child_ != 2 || NULL == node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(node->num_child_), K(node->children_));
} else if (OB_UNLIKELY(NULL == node->children_[0])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL", K(ret), K(node->children_[2]));
} else {
if (T_IDENT == node->children_[0]->type_) {
if (ObCharset::case_insensitive_equal(
ObString(node->children_[0]->str_len_, node->children_[0]->str_value_),
show_resv_ctx.column_name_)) {
node->children_[0]->str_value_ = "table_name";
node->children_[0]->str_len_ = strlen("table_name");
}
} else if (OB_FAIL(replace_where_clause(node->children_[0], show_resv_ctx))) {
LOG_WARN("failed replace expr", K(ret));
}
if (OB_SUCC(ret) && OB_NOT_NULL(node->children_[1])) {
if (OB_FAIL(replace_where_clause(node->children_[1], show_resv_ctx))) {
LOG_WARN("failed replace expr", K(ret));
}
}
}
break;
}
case T_OP_EXISTS:
case T_ANY:
case T_ALL: {
if (OB_UNLIKELY(node->num_child_ < 1 || NULL == node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(node->num_child_), K(node->children_));
} else if (OB_UNLIKELY(NULL == node->children_[0]
|| T_SELECT != node->children_[0]->type_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL",
K(ret),
K(node->children_[0]));
} else {
if (OB_FAIL(replace_where_clause(node->children_[0], show_resv_ctx))) {
LOG_WARN("failed replace expr", K(ret));
}
}
break;
}
case T_OP_NOT: {
ParseNode *cur_expr = node;
while (OB_SUCCESS == ret && cur_expr && cur_expr->type_ == T_OP_NOT) {
if (OB_UNLIKELY(cur_expr->num_child_ < 1 || NULL == cur_expr->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(cur_expr->num_child_), K(cur_expr->children_));
} else {
cur_expr = cur_expr->children_[0];
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(replace_where_clause(cur_expr, show_resv_ctx))) {
LOG_WARN("failed replace expr", K(ret));
}
}
break;
}
case T_OP_POS:
case T_OP_NEG: {
ParseNode *cur_expr = node;
while (OB_SUCCESS == ret
&& cur_expr
&& cur_expr
&& (cur_expr->type_ == T_OP_POS || cur_expr->type_ == T_OP_NEG)) {
if (OB_UNLIKELY(cur_expr->num_child_ < 1 || NULL == cur_expr->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(cur_expr->num_child_), K(cur_expr->children_));
} else {
cur_expr = cur_expr->children_[0];
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(replace_where_clause(cur_expr, show_resv_ctx))) {
LOG_WARN("failed replace expr", K(ret));
}
}
break;
}
case T_OP_AND:
case T_OP_OR:
case T_OP_ADD:
case T_OP_MINUS:
case T_OP_MUL:
case T_OP_DIV:
case T_OP_REM:
case T_OP_BIT_AND:
case T_OP_BIT_OR:
case T_OP_BIT_XOR:
case T_OP_BIT_LEFT_SHIFT:
case T_OP_BIT_RIGHT_SHIFT:
case T_OP_POW:
case T_OP_MOD:
case T_OP_INT_DIV:
case T_OP_LE:
case T_OP_LT:
case T_OP_EQ:
case T_OP_GE:
case T_OP_GT:
case T_OP_NE:
case T_OP_IS:
case T_OP_IS_NOT:
case T_OP_CNN:
case T_OP_REGEXP:
case T_OP_NOT_REGEXP:
case T_OP_IN:
case T_OP_NOT_IN: {
if (OB_UNLIKELY(node->num_child_ != 2 || NULL == node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(node->num_child_), K(node->children_));
} else {
if (OB_FAIL(replace_where_clause(node->children_[0], show_resv_ctx))) {
LOG_WARN("failed replace expr", K(ret));
} else if (OB_FAIL(replace_where_clause(node->children_[1], show_resv_ctx))){
LOG_WARN("failed replace expr", K(ret));
}
}
break;
}
case T_OP_LIKE:
case T_OP_NOT_LIKE: {
if (OB_UNLIKELY(!(node->num_child_ == 3 || node->num_child_ == 2) || NULL == node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(node->num_child_), K(node->children_));
} else if (node->num_child_ == 3){
if (OB_FAIL(replace_where_clause(node->children_[0], show_resv_ctx))) {
LOG_WARN("failed replace expr", K(ret));
} else if (OB_FAIL(replace_where_clause(node->children_[1], show_resv_ctx))){
LOG_WARN("failed replace expr", K(ret));
} else if (OB_FAIL(replace_where_clause(node->children_[2], show_resv_ctx))){
LOG_WARN("failed replace expr", K(ret));
}
} else if (node->num_child_ == 2) {
if (OB_FAIL(replace_where_clause(node->children_[0], show_resv_ctx))) {
LOG_WARN("failed replace expr", K(ret));
} else if (OB_FAIL(replace_where_clause(node->children_[1], show_resv_ctx))){
LOG_WARN("failed replace expr", K(ret));
}
}
break;
}
case T_OP_BTW:
case T_OP_NOT_BTW: {
if (OB_UNLIKELY(node->num_child_ != 3 || NULL == node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(node->num_child_), K(node->children_));
} else {
if (OB_FAIL(replace_where_clause(node->children_[0], show_resv_ctx))) {
LOG_WARN("failed replace expr", K(ret));
} else if (OB_FAIL(replace_where_clause(node->children_[1], show_resv_ctx))){
LOG_WARN("failed replace expr", K(ret));
} else if (OB_FAIL(replace_where_clause(node->children_[2], show_resv_ctx))){
LOG_WARN("failed replace expr", K(ret));
}
}
break;
}
case T_CASE: {
if (OB_UNLIKELY(node->num_child_ != 3 || NULL == node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(node->num_child_), K(node->children_));
} else if (OB_UNLIKELY(NULL == node->children_[1]
|| T_WHEN_LIST != node->children_[1]->type_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL",
K(ret),
K(node->children_[1]));
} else {
if (node->children_[0]) {
if (OB_FAIL(replace_where_clause(node->children_[0], show_resv_ctx))) {
LOG_WARN("failed replace expr", K(ret));
break;
}
}
ParseNode *when_node;
for (int32_t i = 0; OB_SUCC(ret) && i < node->children_[1]->num_child_; i++) {
if (OB_UNLIKELY(NULL == node->children_[1]->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL", K(ret));
} else {
when_node = node->children_[1]->children_[i];
if (OB_UNLIKELY(when_node->num_child_ != 2 || NULL == when_node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(when_node->num_child_), K(when_node->children_));
} else {
if (OB_FAIL(replace_where_clause(when_node->children_[0], show_resv_ctx))) {
LOG_WARN("failed replace expr", K(ret));
break;
} else if (OB_FAIL(replace_where_clause(when_node->children_[1], show_resv_ctx))){
LOG_WARN("failed replace expr", K(ret));
break;
} else {/*do nothing*/}
}
}
}
if (node->children_[2]) {
if (OB_FAIL(replace_where_clause(node->children_[2], show_resv_ctx))) {
LOG_WARN("failed replace expr", K(ret));
break;
}
}
}
break;
}
case T_EXPR_LIST: {
if (OB_UNLIKELY(NULL == node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(node->num_child_), K(node->children_));
} else {
for (int32_t i = 0; OB_SUCC(ret) && i < node->num_child_; i++) {
if (OB_FAIL(replace_where_clause(node->children_[i], show_resv_ctx))) {
LOG_WARN("failed replace expr", K(ret));
}
}
}
break;
}
case T_FUN_SYS: {
if (node->num_child_ >1 ) {
if (OB_UNLIKELY(NULL == node->children_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parse tree is wrong", K(ret), K(node->num_child_), K(node->children_));
} else if (OB_UNLIKELY(NULL == node->children_[1]
|| T_EXPR_LIST != node->children_[1]->type_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("parser tree child is NULL",
K(ret),
K(node->children_[1]));
} else {
int32_t num = node->children_[1]->num_child_;
for (int32_t i = 0; OB_SUCC(ret) && i < num; i++) {
if (OB_FAIL(replace_where_clause(node->children_[1]->children_[i], show_resv_ctx))) {
LOG_WARN("failed replace expr", K(ret));
break;
}
}
}
}
break;
}
default:
ret = OB_ERR_PARSER_SYNTAX;
LOG_WARN("wrong type in expression", K(node->type_));
break;
}
}
return ret;
}
int ObShowResolver::resolve_column_ref_expr(const ObQualifiedName &q_name, ObRawExpr *&real_ref_expr)
{
int ret = OB_SUCCESS;
if (OB_FAIL(resolve_table_column_ref(q_name, real_ref_expr))) {
LOG_WARN("fail to resolve table column_ref", K(ret));
}
return ret;
}
int ObShowResolver::ObSqlStrGenerator::init(common::ObIAllocator *allocator)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(NULL == (sql_buf_ = static_cast<char *>(allocator->alloc(OB_MAX_SQL_LENGTH))))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("failed to alloc sql buf", K(ret), K(OB_MAX_SQL_LENGTH));
}
return ret;
}
int ObShowResolver::ObSqlStrGenerator::gen_select_str(const char *select_str, ...)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(sql_buf_)) {
ret = OB_NOT_INIT;
LOG_WARN("sql buffer is not init", K(ret));
} else {
if (NULL == select_str) {
if (OB_FAIL(databuff_printf(sql_buf_, OB_MAX_SQL_LENGTH, sql_buf_pos_, "SELECT * "))) {
LOG_WARN("fail to add select sql string", K(ret));
}
} else {
va_list select_args;
va_start(select_args, select_str);
if (lib::is_oracle_mode()) {
//show xxx will be banned on oracle mode,so here just replace ` to "
char select_str_o[OB_SHORT_SQL_LENGTH];
int64_t len = strlen(select_str);
int64_t new_len = 0;
for (int i = 0; i < len; i++) {
if ('`' != select_str[i]) {
select_str_o[new_len++] = select_str[i];
} else {
select_str_o[new_len++] = '"';
}
}
select_str_o[new_len] = '\0';
if (OB_FAIL(databuff_vprintf(sql_buf_, OB_MAX_SQL_LENGTH, sql_buf_pos_,
select_str_o, select_args))) {
LOG_WARN("fail to add select sql string", K(ret));
}
} else {
if (OB_FAIL(databuff_vprintf(sql_buf_, OB_MAX_SQL_LENGTH, sql_buf_pos_,
select_str, select_args))) {
LOG_WARN("fail to add select sql string", K(ret));
}
}
va_end(select_args);
}
}
return ret;
}
int ObShowResolver::ObSqlStrGenerator::gen_from_str(const char *subquery_str, ...)
{
int ret = OB_SUCCESS;
HEAP_VAR(char[OB_MAX_SQL_LENGTH], tmp_buf) {
int64_t pos = 0;
if (OB_ISNULL(sql_buf_) || OB_ISNULL(subquery_str)) {
ret = OB_NOT_INIT;
LOG_WARN("sql buffer or subquery_str is not init", K(ret), K(sql_buf_), K(subquery_str));
}
if (lib::is_oracle_mode()) {
//show xxx will be banned on oracle mode,so here just replace ` to "
char new_str[OB_SHORT_SQL_LENGTH];
int64_t len = strlen(subquery_str);
int64_t new_len = 0;
for (int i = 0; i < len; i++) {
if ('`' != subquery_str[i]) {
new_str[new_len++] = subquery_str[i];
} else {
new_str[new_len++] = '"';
}
}
new_str[new_len] = '\0';
if (OB_FAIL(databuff_printf(tmp_buf,
OB_MAX_SQL_LENGTH,
pos,
" FROM (%s) %s",
new_str,
ObShowSqlSet::SUBQERY_ALIAS))) {
LOG_WARN("fail to add subquery sql string", K(ret));
}
} else {
if (OB_FAIL(databuff_printf(tmp_buf,
OB_MAX_SQL_LENGTH,
pos,
" FROM (%s) %s",
subquery_str,
ObShowSqlSet::SUBQERY_ALIAS))) {
LOG_WARN("fail to add subquery sql string", K(ret));
}
}
if (OB_SUCC(ret)) {
va_list subquery_args;
va_start(subquery_args, subquery_str);
if (OB_FAIL(databuff_vprintf(sql_buf_,
OB_MAX_SQL_LENGTH,
sql_buf_pos_,
tmp_buf,
subquery_args))) {
LOG_WARN("fail to add subquery args sql string", K(ret));
}
va_end(subquery_args);
}
}
return ret;
}
int ObShowResolver::ObSqlStrGenerator::gen_limit_str(int64_t offset, int64_t row_cnt)
{
int ret = OB_SUCCESS;
if (OB_FAIL(databuff_printf(sql_buf_,
OB_MAX_SQL_LENGTH,
sql_buf_pos_,
" LIMIT %ld, %ld ",
offset,
row_cnt))) {
LOG_WARN("fail to gen limit string", K(ret));
}
return ret;
}
void ObShowResolver::ObSqlStrGenerator::assign_sql_str(ObString &sql_str)
{
sql_str.assign_ptr(sql_buf_, static_cast<uint32_t>(sql_buf_pos_));
}
}/* ns sql*/
}/* ns oceanbase */
namespace oceanbase
{
namespace sql
{
#define DEFINE_SHOW_CLAUSE(clause_type, string) \
const char *ObShowResolver::ObShowSqlSet::clause_type = string
// @SHOW_STMT_TYPE : 标识show语句的种类,如果相同show语句使用不subquery或select,则需要定义更个不同的SHOW_STMT_TYPE
// @select_str : NULL为采用默认值(默认为"select *"), 其他情况需要自己编写select语句
// @subquery : 此项不能为NULL
// @like_str : like 语句所使用的列,如果该show语句不支持like语法,设置为NULL
#define DEFINE_SHOW_CLAUSE_SET(SHOW_STMT_TYPE, select_str, subquery_str, ora_subquery_str, like_str) \
DEFINE_SHOW_CLAUSE(SHOW_STMT_TYPE##_SELECT, select_str); \
DEFINE_SHOW_CLAUSE(SHOW_STMT_TYPE##_SUBQUERY, subquery_str); \
DEFINE_SHOW_CLAUSE(SHOW_STMT_TYPE##_ORA_SUBQUERY, ora_subquery_str); \
DEFINE_SHOW_CLAUSE(SHOW_STMT_TYPE##_LIKE, like_str)
DEFINE_SHOW_CLAUSE(SUBQERY_ALIAS, "subquery_alias");
DEFINE_SHOW_CLAUSE_SET(SHOW_TABLES,
"SELECT table_name AS `Tables_in_%.*s` ",
"SELECT table_name FROM %s.%s WHERE database_id = %ld ORDER BY table_name COLLATE utf8mb4_bin ASC",
NULL,
"table_name");
DEFINE_SHOW_CLAUSE_SET(SHOW_TABLES_LIKE,
"SELECT table_name AS `Tables_in_%.*s (%.*s)` ",
"SELECT table_name FROM %s.%s WHERE database_id = %ld ORDER BY table_name COLLATE utf8mb4_bin ASC",
NULL,
"table_name");
DEFINE_SHOW_CLAUSE_SET(SHOW_FULL_TABLES,
"SELECT table_name AS `Tables_in_%.*s`, table_type AS `Table_type` ",
"SELECT table_name, table_type FROM %s.%s WHERE database_id = %ld ORDER BY table_name COLLATE utf8mb4_bin ASC",
NULL,
"table_name");
DEFINE_SHOW_CLAUSE_SET(SHOW_FULL_TABLES_LIKE,
"SELECT table_name AS `Tables_in_%.*s (%.*s)`, table_type AS `Table_type` ",
"SELECT table_name, table_type FROM %s.%s WHERE database_id = %ld ORDER BY table_name COLLATE utf8mb4_bin ASC",
NULL,
"table_name");
DEFINE_SHOW_CLAUSE_SET(SHOW_CHARSET,
NULL,
"SELECT charset AS Charset, description AS `Description`, default_collation AS `Default collation`, max_length AS `Maxlen` FROM %s.%s",
R"(SELECT "CHARSET" AS "CHARSET", "DESCRIPTION" AS "DESCRIPTION", "DEFAULT_COLLATION" AS "DEFAULT COLLATION", "MAX_LENGTH" AS "MAXLEN" FROM %s.%s)",
"Charset");
DEFINE_SHOW_CLAUSE_SET(SHOW_TABLEGROUPS,
NULL,
"SELECT t1.Tablegroup_name AS Tablegroup_name, t2.Table_name AS Table_name, t3.Database_name AS Database_name \
FROM %s.%s t1 LEFT JOIN %s.%s t2 ON (t1.tablegroup_id = t2.tablegroup_id and t2.tenant_id = %lu) \
LEFT JOIN %s.%s t3 ON (t2.database_id = t3.database_id and t3.tenant_id = %lu) \
WHERE t1.tenant_id = %lu \
ORDER BY t1.tablegroup_name, t2.table_name",
"SELECT T1.TABLEGROUP_NAME AS \"TABLEGROUP_NAME\", T2.TABLE_NAME AS \"TABLE_NAME\", T3.DATABASE_NAME AS \"DATABASE_NAME\" \
FROM %s.%s T1 LEFT JOIN %s.%s T2 ON (T1.TABLEGROUP_ID = T2.TABLEGROUP_ID AND T2.TENANT_ID = %lu) \
LEFT JOIN %s.%s T3 ON (T2.DATABASE_ID = T3.DATABASE_ID AND T3.TENANT_ID = %lu) \
WHERE T1.TENANT_ID = %lu \
ORDER BY T1.TABLEGROUP_NAME, T2.TABLE_NAME",
"Tablegroup_name");
DEFINE_SHOW_CLAUSE_SET(SHOW_TABLEGROUPS_V2,
NULL,
"SELECT t1.Tablegroup_name AS Tablegroup_name, t2.Table_name AS Table_name, t3.Database_name AS Database_name, t1.Sharding AS Sharding \
FROM %s.%s t1 LEFT JOIN %s.%s t2 ON (t1.tablegroup_id = t2.tablegroup_id and t2.tenant_id = %lu AND t2.table_type in (0, 3, 6)) \
LEFT JOIN %s.%s t3 ON (t2.database_id = t3.database_id and t3.tenant_id = %lu) \
WHERE t1.tenant_id = %lu \
ORDER BY t1.tablegroup_name, t2.table_name",
"SELECT T1.TABLEGROUP_NAME AS \"TABLEGROUP_NAME\", T2.TABLE_NAME AS \"TABLE_NAME\", T3.DATABASE_NAME AS \"DATABASE_NAME\", t1.SHARDING AS \"SHARDING\" \
FROM %s.%s T1 LEFT JOIN %s.%s T2 ON (T1.TABLEGROUP_ID = T2.TABLEGROUP_ID AND T2.TENANT_ID = %lu AND T2.TABLE_TYPE in (0, 3, 6)) \
LEFT JOIN %s.%s T3 ON (T2.DATABASE_ID = T3.DATABASE_ID AND T3.TENANT_ID = %lu) \
WHERE T1.TENANT_ID = %lu \
ORDER BY T1.TABLEGROUP_NAME, T2.TABLE_NAME",
"Tablegroup_name");
DEFINE_SHOW_CLAUSE_SET(SHOW_VARIABLES,
NULL,
"SELECT /*+parallel(1)*/ variable_name AS `Variable_name`, value AS `Value` FROM %s.%s ORDER BY variable_name ASC",
R"(SELECT /*+parallel(1)*/ "VARIABLE_NAME" AS "VARIABLE_NAME", "VALUE" AS "VALUE" FROM %s.%s ORDER BY VARIABLE_NAME ASC)",
"Variable_name");
DEFINE_SHOW_CLAUSE_SET(SHOW_GLOBAL_VARIABLES,
NULL,
"SELECT /*+parallel(1)*/ variable_name AS `Variable_name`, value AS `Value` FROM %s.%s ORDER BY variable_name ASC",
R"(SELECT /*+parallel(1)*/ "VARIABLE_NAME" AS "VARIABLE_NAME", "VALUE" AS "VALUE" FROM %s.%s ORDER BY VARIABLE_NAME ASC)",
"Variable_name");
DEFINE_SHOW_CLAUSE_SET(SHOW_COLUMNS,
NULL,
"SELECT field AS `Field`, type AS `Type`, `NULL` AS `Null`, `KEY` AS `Key`, `DEFAULT` AS `Default`, extra AS `Extra` \
FROM %s.%s where table_id = %ld",
R"(SELECT "FIELD" AS "FIELD", "TYPE" AS "TYPE", "NULL" AS "NULL", "KEY" AS "KEY", "DEFAULT" AS "DEFAULT", "EXTRA" AS "EXTRA" )"
R"(FROM %s.%s WHERE TABLE_ID = %ld)",
"Field");
DEFINE_SHOW_CLAUSE_SET(SHOW_FULL_COLUMNS,
NULL,
"SELECT field AS `Field`, type AS `Type`, collation AS `Collation`, `NULL` AS `Null`, `KEY` AS `Key`, `DEFAULT` AS `Default`, extra AS `Extra`, `PRIVILEGES` AS `Privileges`, `COMMENT` AS `Comment` \
FROM %s.%s where table_id = %ld",
R"(SELECT "FIELD" AS "FIELD", "TYPE" AS "TYPE", "COLLATION" AS "COLLATION", "NULL" AS "NULL", KEY AS "KEY", "DEFAULT" AS "DEFAULT", EXTRA AS "EXTRA", "PRIVILEGES" AS "PRIVILEGES", "COMMENT" AS "COMMENT" )"
R"(FROM %s.%s WHERE TABLE_ID = %ld)",
"Field");
DEFINE_SHOW_CLAUSE_SET(SHOW_CREATE_DATABASE,
NULL,
"SELECT `database_name` AS `Database`, create_database AS `Create Database` FROM %s.%s WHERE database_id = %ld",
NULL,
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_CREATE_DATABASE_EXISTS,
NULL,
"SELECT `database_name` AS `Database`, create_database_with_if_not_exists AS `Create Database` FROM %s.%s WHERE database_id = %ld",
NULL,
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_CREATE_TABLEGROUP,
NULL,
"SELECT tablegroup_name AS `Tablegroup`, create_tablegroup AS `Create Tablegroup` FROM %s.%s WHERE tablegroup_id = %ld",
R"(SELECT "TABLEGROUP_NAME" AS "TABLEGROUP", "CREATE_TABLEGROUP" AS "CREATE TABLEGROUP" FROM %s.%s WHERE TABLEGROUP_ID = %ld)",
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_INDEXES,
NULL,
"SELECT `TABLE` AS `Table`, NON_UNIQUE AS Non_unique, KEY_NAME AS Key_name, SEQ_IN_INDEX AS Seq_in_index, COLUMN_NAME AS Column_name, COLLATION AS Collation, CARDINALITY AS Cardinality, SUB_PART AS Sub_part, PACKED AS Packed, `NULL` AS `Null`, INDEX_TYPE AS Index_type, `COMMENT` AS `Comment`, INDEX_COMMENT AS Index_comment, IS_VISIBLE AS Visible, EXPRESSION AS Expression FROM %s.%s where table_id = %ld",
R"(SELECT "TABLE" AS "TABLE", "NON_UNIQUE" AS "NON_UNIQUE", "KEY_NAME" AS "KEY_NAME", "SEQ_IN_INDEX" AS "SEQ_IN_INDEX", "COLUMN_NAME" AS "COLUMN_NAME", "COLLATION" AS "COLLATION", "CARDINALITY" AS "CARDINALITY", "SUB_PART" AS "SUB_PART", "PACKED" AS "PACKED", "NULL" AS "NULL", "INDEX_TYPE" AS "INDEX_TYPE", "COMMENT" AS "COMMENT", )"
R"(INDEX_COMMENT" AS "INDEX_COMMENT", "IS_VISIBLE" AS "VISIBLE", "EXPRESSION" AS "EXPRESSION" FROM %s.%s WHERE TABLE_ID = %ld")",
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_TRACE,
NULL,
"SELECT span_name as `Operation`, start_ts as `StartTime`, concat(cast(elapse/1000 as number(20, 3)), ' ms') as `ElapseTime` from %s.%s",
R"(SELECT span_name as "OPERATION", to_char(start_ts,'yyyy-mm-dd hh24:mi:ss') as "START_TIME", concat(to_char(elapse/1000, 'FM99999999999999990.000'), ' ms') as "ELAPSE_TIME" FROM %s.%s)",
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_TRACE_JSON,
NULL,
"select json_arrayagg(json_object('tenant_id', tenant_id, 'trace_id', trace_id, 'rec_svr_ip', rec_svr_ip, 'rec_svr_port', rec_svr_port, 'parent', parent_span_id, 'span_id', span_id, 'span_name', span_name, 'start_ts', start_ts, 'end_ts', end_ts, 'elapse', elapse, 'tags', cast(case when tags='' then NULL else tags end as json), 'logs', cast(case when logs='' then NULL else logs end as json))) as ShowTraceJSON from %s.%s",
R"(select json_arrayagg(json_object('tenant_id' : tenant_id, 'trace_id' : trace_id, 'rec_svr_ip' : rec_svr_ip, 'rec_svr_port' : rec_svr_port, 'parent' : parent_span_id, 'span_id' : span_id, 'span_name' : span_name, 'start_ts' : cast(start_ts as varchar(100)), 'end_ts' : cast(end_ts as varchar(100)), 'elapse' : elapse, 'tags' : cast(tags as json), 'logs' : cast(logs as json) returning json) returning json) as SHOW_TRACE_JSON from %s.%s)",
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_ENGINES,
NULL,
"SELECT * FROM %s.%s ",
NULL,
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_PRIVILEGES,
NULL,
"SELECT * FROM %s.%s ",
"SELECT * FROM %s.%s ",
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_QUERY_RESPONSE_TIME,
NULL,
"SELECT response_time as RESPONSE_TIME, count as COUNT, total as TOTAL FROM %s.%s where tenant_id = %lu",
NULL,
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_COLLATION,
NULL,
"SELECT collation AS `Collation`, charset AS `Charset`, id AS `Id`, is_default AS `Default`, is_compiled AS `Compiled`, sortlen AS `Sortlen` FROM %s.%s ",
R"(SELECT "COLLATION" AS "COLLATION", "CHARSET" AS "CHARSET", "ID" AS "ID", "IS_DEFAULT" AS "DEFAULT", "IS_COMPILED" AS "COMPILED", "SORTLEN" AS "SORTLEN" FROM %s.%s )",
"Collation");
DEFINE_SHOW_CLAUSE_SET(SHOW_GRANTS,
"SELECT grants AS `Grants for %.*s@%.*s` ",
"SELECT grants FROM %s.%s WHERE user_id = %ld",
R"(SELECT "GRANTS" AS "GRANTS" FROM %s.%s WHERE USER_ID = %ld)",
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_PROCESSLIST,
NULL,
"SELECT id AS `Id`, user AS `User`, host AS `Host`, db AS `db`, command AS `Command`, time AS `Time`, state AS `State`, info AS `Info` FROM %s.%s WHERE is_serving_tenant(svr_ip, svr_port, %ld)=1",
R"(SELECT "ID" AS "ID", "USER" AS "USER", "HOST" AS "HOST", "DB" AS "DB", "COMMAND" AS "COMMAND", "TIME" AS "TIME", "STATE" AS "STATE", "INFO" AS "INFO" FROM %s.%s WHERE IS_SERVING_TENANT(SVR_IP, SVR_PORT, %ld)=1)",
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_FULL_PROCESSLIST,
NULL,
"SELECT id AS `Id`, user as `User`, tenant as `Tenant`, host AS `Host`, db AS `db`, command AS `Command`, time AS `Time`, state AS `State`, info AS `Info` , svr_ip AS `Ip`, sql_port AS `Port` FROM %s.%s WHERE is_serving_tenant(svr_ip, svr_port, %ld)=1",
R"(SELECT "ID" AS "ID", "USER" AS "USER", "TENANT" AS "TENANT", "HOST" AS "HOST", "DB" AS "DB", "COMMAND" AS "COMMAND", "TIME" AS "TIME", "STATE" AS "STATE", "INFO" AS "INFO" , "SVR_IP" AS "IP", "SQL_PORT" AS "PORT" FROM %s.%s WHERE IS_SERVING_TENANT(SVR_IP, SVR_PORT, %ld)=1)",
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_SYS_PROCESSLIST,
NULL,
"SELECT id AS `Id`, user AS `User`, host AS `Host`, db AS `db`, command AS `Command`, time AS `Time`, state AS `State`, info AS `Info` FROM %s.%s",
R"(SELECT "ID" AS "ID", "USER" AS "USER", "HOST" AS "HOST", "DB" AS "DB", "COMMAND" AS "COMMAND", "TIME" AS "TIME", "STATE" AS "STATE", "INFO" AS "INFO" FROM %s.%s)",
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_SYS_FULL_PROCESSLIST,
NULL,
"SELECT id AS `Id`, user as `User`, tenant as `Tenant`, host AS `Host`, db AS `db`, command AS `Command`, time AS `Time`, state AS `State`, info AS `Info` , svr_ip AS `Ip`, sql_port AS `Port`, proxy_sessid AS `Proxy_sessid` FROM %s.%s",
R"(SELECT "ID" AS "ID", "USER" AS "USER", "TENANT" AS "TENANT", "HOST" AS "HOST", "DB" AS "DB", "COMMAND" AS "COMMAND", "TIME" AS "TIME", "STATE" AS "STATE", "INFO" AS "INFO" , "SVR_IP" AS "IP", "SQL_PORT" AS "PORT", "PROXY_SESSID" AS "PROXY_SESSID" FROM %s.%s)",
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_TABLE_STATUS,
NULL,
"SELECT table_name AS `Name`, engine as `Engine`, version as `Version`, row_format as `Row_format`, `ROWS` as `Rows`, avg_row_length as `Avg_row_length`, data_length as `Data_length`, max_data_length as `Max_data_length`, index_length as `Index_length`, data_free as `Data_free`, auto_increment as `Auto_increment`, create_time as `Create_time`, update_time as `Update_time`, check_time as `Check_time`, collation as `Collation`, checksum as `Checksum`, create_options as `Create_options`, `COMMENT` as `Comment` FROM %s.%s WHERE database_id = %ld ORDER BY name COLLATE utf8mb4_bin ASC",
R"(SELECT "TABLE_NAME" AS "NAME", "ENGINE", "VERSION", "ROW_FORMAT", "ROWS" AS "ROWS", "AVG_ROW_LENGTH", "DATA_LENGTH", "MAX_DATA_LENGTH", "INDEX_LENGTH", "DATA_FREE", "AUTO_INCREMENT", "CREATE_TIME", "UPDATE_TIME", "CHECK_TIME", "COLLATION", "CHECKSUM", "CREATE_OPTIONS", "COMMENT" AS "COMMENT" FROM %s.%s WHERE DATABASE_ID = %ld ORDER BY NAME COLLATE UTF8MB4_BIN ASC)",
"name");
DEFINE_SHOW_CLAUSE_SET(SHOW_PROCEDURE_STATUS,
NULL,
"select database_name AS `Db`, routine_name AS `Name`, c.type AS `Type`, c.definer AS `Definer`, p.gmt_modified AS `Modified`, p.gmt_create AS `Created`, c.security_type AS `Security_type`, p.comment AS `Comment`, character_set_client, collation_connection, db_collation AS `Database Collation`from %s.%s p, %s.%s d, %s.%s c where p.tenant_id = d.tenant_id and p.database_id = d.database_id and d.database_name = c.db and p.routine_name = c.name and (case c.type when 'PROCEDURE' then 1 when 'FUNCTION' then 2 else 0 end) = p.routine_type and d.database_id = %ld and p.routine_type = %ld ORDER BY name COLLATE utf8mb4_bin ASC",
NULL,
"name");
DEFINE_SHOW_CLAUSE_SET(SHOW_TRIGGERS,
NULL,
"select t.trigger_name as `Trigger`, t.event_manipulation as `Event`, t.event_object_table as `Table`, t.action_statement as `Statement`, t.action_timing as `Timing`, t.created as `Created`, t.sql_mode as `sql_mode`, t.definer as `Definer`, t.character_set_client as `character_set_client`, t.collation_connection as `collation_connection`, t.database_collation as `Database Collation` from %s.%s t, %s.%s d where t.event_object_schema = d.database_name and d.database_id = %ld ",
NULL,
"Trigger");
DEFINE_SHOW_CLAUSE_SET(SHOW_TRIGGERS_LIKE,
NULL,
"select t.trigger_name as `Trigger`, t.event_manipulation as `Event`, t.event_object_table as `Table`, t.action_statement as `Statement`, t.action_timing as `Timing`, t.created as `Created`, t.sql_mode as `sql_mode`, t.definer as `Definer`, t.character_set_client as `character_set_client`, t.collation_connection as `collation_connection`, t.database_collation as `Database Collation` from %s.%s t, %s.%s d where t.event_object_schema = d.database_name and d.database_id = %ld ",
NULL,
"Table");
DEFINE_SHOW_CLAUSE_SET(SHOW_WARNINGS,
NULL,
"SELECT `level` AS `Level`, `code` AS `Code`, `message` AS `Message` FROM %s.%s ",
NULL,
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_COUNT_WARNINGS,
NULL,
"SELECT count(*) AS `@@session.warning_count` FROM %s.%s ",
NULL,
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_ERRORS,
NULL,
"SELECT `level` AS `Level`, `code` AS `Code`, `message` AS `Message` FROM %s.%s WHERE `level` = \'Error\'",
NULL,
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_COUNT_ERRORS,
NULL,
"SELECT count(*) AS `@@session.error_count` FROM %s.%s WHERE `level` = \'Error\'",
NULL,
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_PARAMETERS,
NULL,
"SELECT zone, svr_type, svr_ip, svr_port, name, data_type, value, info, section, scope, source, edit_level from %s.%s where name not like '\\_%%' and (tenant_id = %ld or tenant_id is null)",
R"(SELECT "ZONE", "SVR_TYPE", "SVR_IP", "SVR_PORT", "NAME", "DATA_TYPE", "VALUE", "INFO", "SECTION", "SCOPE", "SOURCE", "EDIT_LEVEL" FROM %s.%s WHERE NAME NOT LIKE '\_%%' ESCAPE '\' and (tenant_id = %ld or tenant_id is null))",
"name");
DEFINE_SHOW_CLAUSE_SET(SHOW_PARAMETERS_UNSYS,
NULL,
"SELECT 1 `gmt_create`, 1 `gmt_modified`, 1 `zone`, 1 `svr_type`, 1 `svr_ip`, 1 `svr_port`, 1 `name`, 1 `data_type`, 1 `value`, 1 `info`, 1 `section`, 1 `scope`, 1 `source`, 1 `edit_level` FROM (SELECT 1 FROM DUAL) tmp_table WHERE 1 != 1",
R"(SELECT 1 "GMT_CREATE", 1 "GMT_MODIFIED", 1 "ZONE", 1 "SVR_TYPE", 1 "SVR_IP", 1 "SVR_PORT", 1 "NAME", 1 "DATA_TYPE", 1 "VALUE", 1 "INFO", 1 "SECTION", 1 "SCOPE" , 1 "SOURCE", 1 "EDIT_LEVEL" FROM (SELECT 1 FROM DUAL) TMP_TABLE WHERE 1 != 1)",
"name");
DEFINE_SHOW_CLAUSE_SET(SHOW_PARAMETERS_COMPAT,
NULL,
"SELECT zone, svr_type, svr_ip, svr_port, name, data_type, value, info, section from %s.%s where name not like '\\_%%'",
R"(SELECT "ZONE", "SVR_TYPE", "SVR_IP", "SVR_PORT", "NAME", "DATA_TYPE", "VALUE", "INFO", "SECTION" FROM %s.%s WHERE NAME NOE LIKE '\\_%%')",
"name");
DEFINE_SHOW_CLAUSE_SET(SHOW_PARAMETERS_SEED,
NULL,
"SELECT zone, svr_type, svr_ip, svr_port, name, data_type, value, info, section from %s.%s where svr_ip = '%s' and svr_port = %ld ",
R"(SELECT "ZONE", "SVR_TYPE", "SVR_IP", "SVR_PORT", "NAME", "DATA_TYPE", "VALUE", "INFO", "SECTION" FROM %s.%s WHERE "SVR_IP" = '%s' and "SVR_PORT" = %ld )",
"name");
DEFINE_SHOW_CLAUSE_SET(SHOW_SESSION_STATUS,
NULL,
"select variable_name as Variable_name, variable_value as Value from %s.%s",
NULL,
"Variable_name");
DEFINE_SHOW_CLAUSE_SET(SHOW_GLOBAL_STATUS,
NULL,
"select variable_name as Variable_name, variable_value as Value from %s.%s",
NULL,
"Variable_name");
DEFINE_SHOW_CLAUSE_SET(SHOW_TENANT,
NULL,
"select `tenant_name` as `Current_tenant_name` from %s.%s where tenant_id = %ld",
NULL,
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_TENANT_STATUS,
NULL,
"select tenant as `Tenant`, case when sum(read_only) = 0 then \'read write\' when sum(read_only) < count(read_only) then \'partially read only\' else \'read only\' end as `Status` from %s.%s group by tenant",
NULL,
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_CREATE_TENANT,
NULL,
"select `tenant_name` as `Tenant`, `create_stmt` as `Create Tenant` from %s.%s where tenant_id = %ld",
NULL,
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_DATABASES,
NULL,
"SELECT `database_name` AS `Database` FROM %s.%s WHERE tenant_id = %ld and in_recyclebin = 0 and database_name not in('%s', '%s', '%s') and 0 = sys_privilege_check(\'db_acc\', `tenant_id`, `database_name`, \'\') order by database_name asc",
NULL,
"Database");
DEFINE_SHOW_CLAUSE_SET(SHOW_DATABASES_LIKE,
"SELECT `Database` AS `Database (%.*s)` ",
"SELECT `database_name` AS `Database` FROM %s.%s WHERE tenant_id = %ld and in_recyclebin = 0 and database_name not in ('%s', '%s', '%s') and 0 = sys_privilege_check(\'db_acc\', `tenant_id`, `database_name`, \'\') order by database_name asc",
NULL,
"Database");
DEFINE_SHOW_CLAUSE_SET(SHOW_DATABASES_STATUS,
NULL,
"select db as `Database`, case when sum(read_only) = 0 then \'read write\' when sum(read_only) < count(read_only) then \'partially read only\' else \'read only\' end as `Status` from %s.%s group by db",
NULL,
"Database");
DEFINE_SHOW_CLAUSE_SET(SHOW_DATABASES_STATUS_LIKE,
"SELECT `Database` AS `Database (%.*s)`, `Status` ",
"select db as `Database`, case when sum(read_only) = 0 then \'read write\' when sum(read_only) < count(read_only) then \'partially read only\' else \'read only\' end as `Status` from %s.%s group by db",
NULL,
"Database");
DEFINE_SHOW_CLAUSE_SET(SHOW_CREATE_TABLE,
NULL,
"SELECT table_name AS `Table`, create_table AS `Create Table` FROM %s.%s WHERE table_id = %ld",
R"(SELECT "TABLE_NAME" AS "TABLE", "CREATE_TABLE" AS "CREATE TABLE" FROM %s.%s WHERE TABLE_ID = %ld)",
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_CREATE_VIEW,
NULL,
"SELECT table_name AS `View`, create_table AS `Create View` , character_set_client, collation_connection FROM %s.%s WHERE table_id = %ld",
R"(SELECT "TABLE_NAME" AS "VIEW", "CREATE_TABLE" AS "CREATE VIEW" , "CHARACTER_SET_CLIENT", "COLLATION_CONNECTION" FROM %s.%s WHERE TABLE_ID = %ld)",
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_CREATE_PROCEDURE,
NULL,
"SELECT routine_name AS `Procedure`, sql_mode, create_routine AS `Create Procedure`, character_set_client, collation_connection, collation_database AS `Database Collation` FROM %s.%s WHERE routine_id = %ld and proc_type = %ld",
R"(SELECT "ROUTINE_NAME" AS "PROCEDURE", "SQL_MODE", "CREATE_ROUTINE" AS "CREATE PROCEDURE", "CHARACTER_SET_CLIENT", "COLLATION_CONNECTION", "COLLATION_DATABASE" AS "DATABASE COLLATION" FROM %s.%s WHERE ROUTINE_ID = %ld AND PROC_TYPE = %ld)",
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_CREATE_FUNCTION,
NULL,
"SELECT routine_name AS `Function`, sql_mode, create_routine AS `Create Function`, character_set_client, collation_connection, collation_database AS `Database Collation` FROM %s.%s WHERE routine_id = %ld and proc_type = %ld",
R"(SELECT "ROUTINE_NAME" AS "FUNCTION", "SQL_MODE", "CREATE_ROUTINE" AS "CREATE FUNCTION", "CHARACTER_SET_CLIENT", "COLLATION_CONNECTION", "COLLATION_DATABASE" AS "DATABASE COLLATION" FROM %s.%s WHERE ROUTINE_ID = %ld AND PROC_TYPE = %ld)",
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_CREATE_TRIGGER,
NULL,
"SELECT trigger_name AS `Trigger`, sql_mode, create_trigger AS `SQL Original Statement`, character_set_client, collation_connection, collation_database AS `Database Collation` FROM %s.%s WHERE trigger_id = %ld",
R"(SELECT trigger_name AS "TRIGGER", "SQL_MODE", "CREATE_TRIGGER", "CHARACTER_SET_CLIENT", "COLLATION_CONNECTION", "COLLATION_DATABASE" FROM %s.%s WHERE trigger_id = %ld)",
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_RECYCLEBIN,
"SELECT OBJECT_NAME, ORIGINAL_NAME, TYPE, CREATETIME",
"SELECT OBJECT_NAME, ORIGINAL_NAME, case TYPE when 1 then 'TABLE' when 2 then 'INDEX' when 3 then 'VIEW' when 4 then 'DATABASE' when 5 then 'AUX_VP' when 6 then 'TRIGGER' when 7 then 'TENANT' else 'INVALID' end as TYPE, gmt_create as CREATETIME FROM %s.%s WHERE TYPE != 8 AND TYPE != 9",
R"(SELECT "OBJECT_NAME", "ORIGINAL_NAME", CASE "TYPE" WHEN 1 THEN 'TABLE' WHEN 2 THEN 'INDEX' WHEN 3 THEN 'VIEW' WHEN 4 THEN 'DATABASE' when 5 then 'AUX_VP' when 6 then 'TRIGGER' WHEN 7 THEN 'TENANT' ELSE 'INVALID' END AS "TYPE", "GMT_CREATE" AS "CREATETIME" FROM %s.%s WHERE TYPE != 8 AND TYPE != 9)",
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_RESTORE_PREVIEW,
NULL,
"SELECT * FROM %s.%s",
NULL,
NULL);
DEFINE_SHOW_CLAUSE_SET(SHOW_SEQUENCES,
"SELECT sequence_name AS `Sequences_in_%.*s` ",
"SELECT sequence_name FROM %s.%s WHERE database_id = %ld ORDER BY sequence_name COLLATE utf8mb4_bin ASC",
NULL,
"sequence_name");
DEFINE_SHOW_CLAUSE_SET(SHOW_SEQUENCES_LIKE,
"SELECT sequence_name AS `Sequences_in_%.*s (%.*s)` ",
"SELECT sequence_name FROM %s.%s WHERE database_id = %ld ORDER BY sequence_name COLLATE utf8mb4_bin ASC",
NULL,
"sequence_name");
}/* ns sql*/
}/* ns oceanbase */