support set names/charset and variables in one sql
This commit is contained in:
parent
fa9b5fdfc0
commit
878c594b56
@ -173,14 +173,14 @@ int ObSyncCmdDriver::process_schema_version_changes(const ObMySQLResultSet& resu
|
||||
if (result.get_stmt_type() == stmt::T_VARIABLE_SET) {
|
||||
const ObVariableSetStmt* set_stmt = static_cast<const ObVariableSetStmt*>(result.get_cmd());
|
||||
if (NULL != set_stmt) {
|
||||
ObVariableSetStmt::VariableSetNode tmp_node; // just for init node
|
||||
ObVariableSetStmt::VariableNamesSetNode tmp_node; // just for init node
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < set_stmt->get_variables_size(); ++i) {
|
||||
ObVariableSetStmt::VariableSetNode& var_node = tmp_node;
|
||||
ObVariableSetStmt::VariableNamesSetNode& var_node = tmp_node;
|
||||
ObString set_var_name(OB_SV_LAST_SCHEMA_VERSION);
|
||||
if (OB_FAIL(set_stmt->get_variable_node(i, var_node))) {
|
||||
LOG_WARN("fail to get_variable_node", K(i), K(ret));
|
||||
} else {
|
||||
if (ObCharset::case_insensitive_equal(var_node.variable_name_, set_var_name)) {
|
||||
} else if (var_node.is_set_variable_) {
|
||||
if (ObCharset::case_insensitive_equal(var_node.var_set_node_.variable_name_, set_var_name)) {
|
||||
if (OB_FAIL(check_and_refresh_schema(tenant_id))) {
|
||||
LOG_WARN("failed to check_and_refresh_schema", K(ret), K(tenant_id));
|
||||
}
|
||||
|
@ -984,7 +984,6 @@ int ObMPQuery::is_readonly_stmt(ObMySQLResultSet& result, bool& is_readonly)
|
||||
case stmt::T_SHOW_GRANTS:
|
||||
case stmt::T_SHOW_RECYCLEBIN:
|
||||
case stmt::T_USE_DATABASE:
|
||||
case stmt::T_SET_NAMES: // read only not restrict it
|
||||
case stmt::T_START_TRANS:
|
||||
case stmt::T_END_TRANS: {
|
||||
is_readonly = true;
|
||||
|
@ -99,7 +99,6 @@ ob_set_subtarget(ob_sql engine
|
||||
engine/cmd/ob_resource_executor.cpp
|
||||
engine/cmd/ob_restore_executor.cpp
|
||||
engine/cmd/ob_sequence_executor.cpp
|
||||
engine/cmd/ob_set_names_executor.cpp
|
||||
engine/cmd/ob_set_password_executor.cpp
|
||||
engine/cmd/ob_synonym_executor.cpp
|
||||
engine/cmd/ob_table_executor.cpp
|
||||
@ -835,7 +834,6 @@ ob_set_subtarget(ob_sql resolver
|
||||
resolver/cmd/ob_load_data_resolver.cpp
|
||||
resolver/cmd/ob_load_data_stmt.cpp
|
||||
resolver/cmd/ob_resource_resolver.cpp
|
||||
resolver/cmd/ob_set_names_resolver.cpp
|
||||
resolver/cmd/ob_set_transaction_resolver.cpp
|
||||
resolver/cmd/ob_show_resolver.cpp
|
||||
resolver/cmd/ob_variable_set_resolver.cpp
|
||||
|
@ -1,180 +0,0 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "sql/engine/cmd/ob_set_names_executor.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "lib/string/ob_sql_string.h"
|
||||
#include "share/inner_table/ob_inner_table_schema.h"
|
||||
#include "observer/ob_server_struct.h"
|
||||
using namespace oceanbase::sql;
|
||||
using namespace oceanbase::common;
|
||||
using namespace oceanbase::share;
|
||||
using namespace oceanbase::share::schema;
|
||||
|
||||
int ObSetNamesExecutor::execute(ObExecContext& ctx, ObSetNamesStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* session = NULL;
|
||||
if (NULL == (session = ctx.get_my_session())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(ERROR, "session is NULL", K(ret), K(ctx));
|
||||
} else {
|
||||
ObString charset;
|
||||
if (stmt.is_default_charset()) {
|
||||
// Compatible with mysql, take the global character_set_client value
|
||||
if (OB_FAIL(get_global_sys_var_character_set_client(ctx, charset))) {
|
||||
SQL_ENG_LOG(WARN, "fail to get global character_set_client", K(ret));
|
||||
}
|
||||
} else {
|
||||
charset = stmt.get_charset();
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
ObString collation = stmt.get_collation();
|
||||
ObCollationType collation_type = CS_TYPE_INVALID;
|
||||
ObCharsetType cs_type = ObCharset::charset_type(charset);
|
||||
if (CHARSET_INVALID == cs_type) {
|
||||
ret = OB_ERR_UNKNOWN_CHARSET;
|
||||
LOG_USER_ERROR(OB_ERR_UNKNOWN_CHARSET, charset.length(), charset.ptr());
|
||||
} else {
|
||||
charset = ObString::make_string(ObCharset::charset_name(cs_type));
|
||||
if (stmt.is_default_collation() || !collation.empty()) {
|
||||
collation_type = ObCharset::collation_type(collation);
|
||||
if (CS_TYPE_INVALID == collation_type) {
|
||||
ret = OB_ERR_UNKNOWN_COLLATION;
|
||||
LOG_USER_ERROR(OB_ERR_UNKNOWN_COLLATION, collation.length(), collation.ptr());
|
||||
} else if (!ObCharset::is_valid_collation(cs_type, collation_type)) {
|
||||
ret = OB_ERR_COLLATION_MISMATCH;
|
||||
LOG_USER_ERROR(
|
||||
OB_ERR_COLLATION_MISMATCH, collation.length(), collation.ptr(), charset.length(), charset.ptr());
|
||||
} else {
|
||||
collation = ObString::make_string(ObCharset::collation_name(collation_type));
|
||||
}
|
||||
} else {
|
||||
// the use default collation of this charset
|
||||
collation_type = ObCharset::get_default_collation(cs_type);
|
||||
collation = ObString::make_string(ObCharset::collation_name(collation_type));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (!ObCharset::is_valid_connection_collation(collation_type)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
SQL_ENG_LOG(WARN,
|
||||
"collation type not supported",
|
||||
"charset type",
|
||||
ObCharset::charset_name(cs_type),
|
||||
"collation type",
|
||||
ObCharset::collation_name(collation_type));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (stmt.is_set_names()) {
|
||||
// SET NAMES
|
||||
ObCollationType cs_coll_type = ObCharset::get_default_collation(ObCharset::charset_type(charset));
|
||||
ObCollationType coll_type = ObCharset::collation_type(collation);
|
||||
if (CS_TYPE_INVALID == cs_coll_type || CS_TYPE_INVALID == coll_type) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(ERROR, "cs coll type or coll type is invalid", K(ret), K(cs_coll_type), K(coll_type));
|
||||
} else if (OB_FAIL(session->update_sys_variable(
|
||||
SYS_VAR_CHARACTER_SET_CLIENT, static_cast<int64_t>(cs_coll_type)))) {
|
||||
SQL_ENG_LOG(WARN, "failed to update sys var", K(ret));
|
||||
} else if (OB_FAIL(session->update_sys_variable(
|
||||
SYS_VAR_CHARACTER_SET_RESULTS, static_cast<int64_t>(cs_coll_type)))) {
|
||||
SQL_ENG_LOG(WARN, "failed to update sys var", K(ret));
|
||||
} else if (OB_FAIL(session->update_sys_variable(
|
||||
SYS_VAR_CHARACTER_SET_CONNECTION, static_cast<int64_t>(cs_coll_type)))) {
|
||||
SQL_ENG_LOG(WARN, "failed to update sys var", K(ret));
|
||||
} else if (OB_FAIL(
|
||||
session->update_sys_variable(SYS_VAR_COLLATION_CONNECTION, static_cast<int64_t>(coll_type)))) {
|
||||
SQL_ENG_LOG(WARN, "failed to update sys var", K(ret));
|
||||
}
|
||||
} else {
|
||||
// SET CHARACTER SET
|
||||
ObObj database_charset;
|
||||
ObObj database_collation;
|
||||
ObCollationType cs_coll_type = ObCharset::get_default_collation(ObCharset::charset_type(charset));
|
||||
if (OB_FAIL(session->get_sys_variable(SYS_VAR_CHARACTER_SET_DATABASE, database_charset))) {
|
||||
} else if (OB_FAIL(session->get_sys_variable(SYS_VAR_COLLATION_DATABASE, database_collation))) {
|
||||
} else {
|
||||
ObCollationType collation_connection = static_cast<ObCollationType>(database_collation.get_int());
|
||||
ObCharsetType charset_connection = ObCharset::charset_type_by_coll(collation_connection);
|
||||
if (!ObCharset::is_valid_connection_collation(collation_connection)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
SQL_ENG_LOG(WARN,
|
||||
"connection collation type not supported",
|
||||
"charset type",
|
||||
ObCharset::charset_name(charset_connection),
|
||||
"collation type",
|
||||
ObCharset::collation_name(collation_connection));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(
|
||||
session->update_sys_variable(SYS_VAR_CHARACTER_SET_CLIENT, static_cast<int64_t>(cs_coll_type)))) {
|
||||
SQL_EXE_LOG(WARN, "failed to update sys var", K(ret));
|
||||
} else if (OB_FAIL(session->update_sys_variable(
|
||||
SYS_VAR_CHARACTER_SET_RESULTS, static_cast<int64_t>(cs_coll_type)))) {
|
||||
SQL_EXE_LOG(WARN, "failed to update sys var", K(ret));
|
||||
} else if (OB_FAIL(session->update_sys_variable(SYS_VAR_CHARACTER_SET_CONNECTION, database_charset))) {
|
||||
SQL_EXE_LOG(WARN, "failed to update sys var", K(ret));
|
||||
} else if (OB_FAIL(session->update_sys_variable(SYS_VAR_COLLATION_CONNECTION, database_collation))) {
|
||||
SQL_EXE_LOG(WARN, "failed to update sys var", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSetNamesExecutor::get_global_sys_var_character_set_client(
|
||||
ObExecContext& ctx, ObString& character_set_client) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* session = NULL;
|
||||
ObIAllocator& allocator = ctx.get_allocator();
|
||||
ObSchemaGetterGuard schema_guard;
|
||||
const ObSysVarSchema* var_schema = NULL;
|
||||
ObObj value;
|
||||
if (NULL == (session = ctx.get_my_session())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(ERROR, "session is NULL", K(ret), K(ctx));
|
||||
} else if (OB_ISNULL(GCTX.schema_service_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(ERROR, "schema service is null");
|
||||
} else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard(session->get_effective_tenant_id(), schema_guard))) {
|
||||
SQL_ENG_LOG(WARN, "get schema guard failed", K(ret));
|
||||
} else if (OB_FAIL(schema_guard.get_tenant_system_variable(
|
||||
session->get_effective_tenant_id(), SYS_VAR_CHARACTER_SET_CLIENT, var_schema))) {
|
||||
SQL_ENG_LOG(WARN, "get tenant system variable failed", K(ret));
|
||||
} else if (OB_ISNULL(var_schema)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "var_schema is null");
|
||||
} else if (OB_FAIL(var_schema->get_value(&allocator, ObBasicSessionInfo::create_dtc_params(session), value))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "get value from var_schema failed", K(ret), K(*var_schema));
|
||||
} else if (ObIntType != value.get_type()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(ERROR, "sys var character_set_client's type must be ObIntType", K(ret), K(value));
|
||||
} else {
|
||||
ObCollationType coll_type = static_cast<ObCollationType>(value.get_int());
|
||||
if (!ObCharset::is_valid_collation(coll_type)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "invalid collation type", K(ret), K(coll_type));
|
||||
} else {
|
||||
const char* cs_name_ptr = ObCharset::charset_name(coll_type);
|
||||
character_set_client = ObString(cs_name_ptr);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef _OB_SET_NAMES_EXECUTOR_H
|
||||
#define _OB_SET_NAMES_EXECUTOR_H 1
|
||||
#include "sql/resolver/cmd/ob_set_names_stmt.h"
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObSetNamesExecutor {
|
||||
public:
|
||||
ObSetNamesExecutor()
|
||||
{}
|
||||
virtual ~ObSetNamesExecutor()
|
||||
{}
|
||||
|
||||
int execute(ObExecContext& ctx, ObSetNamesStmt& stmt);
|
||||
|
||||
private:
|
||||
int get_global_sys_var_character_set_client(ObExecContext& ctx, common::ObString& character_set_client) const;
|
||||
|
||||
private:
|
||||
// disallow copy
|
||||
DISALLOW_COPY_AND_ASSIGN(ObSetNamesExecutor);
|
||||
// function members
|
||||
private:
|
||||
// data members
|
||||
};
|
||||
|
||||
} // end namespace sql
|
||||
} // end namespace oceanbase
|
||||
|
||||
#endif /* _OB_SET_NAMES_EXECUTOR_H */
|
@ -39,7 +39,7 @@ using namespace common;
|
||||
using namespace share;
|
||||
using namespace share::schema;
|
||||
namespace sql {
|
||||
int check_sys_var_options(ObExecContext& ctx, const common::ObIArray<ObVariableSetStmt::VariableSetNode>& sys_var_nodes,
|
||||
int check_sys_var_options(ObExecContext& ctx, const common::ObIArray<ObVariableSetStmt::VariableNamesSetNode>& sys_var_nodes,
|
||||
share::schema::ObTenantSchema& tenant_schema, common::ObIArray<obrpc::ObSysVarIdValue>& sys_var_list);
|
||||
|
||||
int ObCreateTenantExecutor::execute(ObExecContext& ctx, ObCreateTenantStmt& stmt)
|
||||
@ -111,7 +111,7 @@ int ObCreateTenantExecutor::execute(ObExecContext& ctx, ObCreateTenantStmt& stmt
|
||||
return ret;
|
||||
}
|
||||
|
||||
int check_sys_var_options(ObExecContext& ctx, const common::ObIArray<ObVariableSetStmt::VariableSetNode>& sys_var_nodes,
|
||||
int check_sys_var_options(ObExecContext& ctx, const common::ObIArray<ObVariableSetStmt::VariableNamesSetNode>& sys_var_nodes,
|
||||
share::schema::ObTenantSchema& tenant_schema, common::ObIArray<obrpc::ObSysVarIdValue>& sys_var_list)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -141,104 +141,110 @@ int check_sys_var_options(ObExecContext& ctx, const common::ObIArray<ObVariableS
|
||||
plan_ctx->has_cur_time() ? plan_ctx->get_cur_time().get_timestamp() : ObTimeUtility::current_time();
|
||||
phy_plan_ctx.set_cur_time(cur_time, *session);
|
||||
|
||||
ObVariableSetStmt::VariableSetNode tmp_node; // just for init node
|
||||
ObVariableSetStmt::VariableNamesSetNode tmp_node; // just for init node
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < sys_var_nodes.count(); ++i) {
|
||||
ObVariableSetStmt::VariableSetNode& cur_node = tmp_node;
|
||||
ObVariableSetStmt::VariableNamesSetNode& var_names_node = tmp_node;
|
||||
ObBasicSysVar* sys_var = NULL;
|
||||
if (OB_FAIL(sys_var_nodes.at(i, cur_node))) {
|
||||
if (OB_FAIL(sys_var_nodes.at(i, var_names_node))) {
|
||||
LOG_WARN("failed to access node from array", K(ret));
|
||||
} else if (!cur_node.is_system_variable_) {
|
||||
} else if (OB_UNLIKELY(!var_names_node.is_set_variable_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("create tenant can only set system variables", K(cur_node), K(ret));
|
||||
} else if (OB_FAIL(session->get_sys_variable_by_name(cur_node.variable_name_, sys_var))) {
|
||||
LOG_WARN("fail to get_sys_variable_by_name", K(ret));
|
||||
} else if (OB_ISNULL(sys_var)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("got sys var is NULL", K(ret));
|
||||
} else if (cur_node.is_set_default_) { // set default, then do nothing
|
||||
LOG_WARN("only expect set variables here", K(ret), K(var_names_node));
|
||||
} else {
|
||||
ObObj value_obj;
|
||||
// first:calculate value of expression
|
||||
ObNewRow tmp_row;
|
||||
RowDesc row_desc;
|
||||
ObExprGeneratorImpl expr_gen(0, 0, NULL, row_desc);
|
||||
ObSqlExpression sql_expr(ctx.get_allocator(), 0);
|
||||
if (OB_ISNULL(cur_node.value_expr_)) {
|
||||
ObVariableSetStmt::VariableSetNode& cur_node = var_names_node.var_set_node_;
|
||||
if (!cur_node.is_system_variable_) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("node.value_expr_ is NULL", K(ret));
|
||||
LOG_WARN("create tenant can only set system variables", K(cur_node), K(ret));
|
||||
} else if (OB_FAIL(session->get_sys_variable_by_name(cur_node.variable_name_, sys_var))) {
|
||||
LOG_WARN("fail to get_sys_variable_by_name", K(ret));
|
||||
} else if (OB_ISNULL(sys_var)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("got sys var is NULL", K(ret));
|
||||
} else if (cur_node.is_set_default_) { // set default, then do nothing
|
||||
} else {
|
||||
if (!is_strict_mode(session->get_sql_mode())) {
|
||||
expr_ctx.cast_mode_ = CM_WARN_ON_FAIL;
|
||||
}
|
||||
if (OB_FAIL(expr_gen.generate(*cur_node.value_expr_, sql_expr))) {
|
||||
LOG_WARN("fail to fill sql expression", K(ret));
|
||||
} else if (FALSE_IT(phy_plan.set_regexp_op_count(expr_gen.get_cur_regexp_op_count()))) {
|
||||
} else if (FALSE_IT(phy_plan.set_like_op_count(expr_gen.get_cur_like_op_count()))) {
|
||||
} else if (OB_FAIL(sql_expr.calc(expr_ctx, tmp_row, value_obj))) {
|
||||
LOG_WARN("fail to calc value", K(*cur_node.value_expr_), K(ret));
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
}
|
||||
// second:convert value to dest type
|
||||
uint64_t fake_tenant_id = OB_INVALID_ID;
|
||||
ObSetVar set_var(cur_node.variable_name_,
|
||||
cur_node.set_scope_,
|
||||
cur_node.is_set_default_,
|
||||
fake_tenant_id,
|
||||
*expr_ctx.calc_buf_,
|
||||
*sql_proxy);
|
||||
if (OB_SUCC(ret)) {
|
||||
ObObj out_obj;
|
||||
const bool is_set_stmt = false;
|
||||
if (OB_FAIL(ObVariableSetExecutor::check_and_convert_sys_var(
|
||||
ctx, set_var, *sys_var, value_obj, out_obj, is_set_stmt))) {
|
||||
LOG_WARN("fail to check_and_convert_sys_var", K(cur_node), K(*sys_var), K(value_obj), K(ret));
|
||||
} else if (FALSE_IT(value_obj = out_obj)) {
|
||||
} else if (OB_FAIL(ObVariableSetExecutor::cast_value(
|
||||
ctx, cur_node, fake_tenant_id, *expr_ctx.calc_buf_, *sys_var, value_obj, out_obj))) {
|
||||
LOG_WARN("fail to cast value", K(cur_node), K(*sys_var), K(value_obj), K(ret));
|
||||
} else if (FALSE_IT(value_obj = out_obj)) {
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
}
|
||||
// add variable value into ObCreateTenantArg
|
||||
if (OB_SUCC(ret)) {
|
||||
if (set_var.var_name_ == OB_SV_COLLATION_SERVER || set_var.var_name_ == OB_SV_COLLATION_DATABASE ||
|
||||
set_var.var_name_ == OB_SV_COLLATION_CONNECTION || set_var.var_name_ == OB_SV_CHARACTER_SET_SERVER ||
|
||||
set_var.var_name_ == OB_SV_CHARACTER_SET_DATABASE ||
|
||||
set_var.var_name_ == OB_SV_CHARACTER_SET_CONNECTION) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("collation or charset can not be modify temporarily", K(set_var), K(ret));
|
||||
ObObj value_obj;
|
||||
// first:calculate value of expression
|
||||
ObNewRow tmp_row;
|
||||
RowDesc row_desc;
|
||||
ObExprGeneratorImpl expr_gen(0, 0, NULL, row_desc);
|
||||
ObSqlExpression sql_expr(ctx.get_allocator(), 0);
|
||||
if (OB_ISNULL(cur_node.value_expr_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("node.value_expr_ is NULL", K(ret));
|
||||
} else {
|
||||
// read only should also modify tenant_schema
|
||||
if (set_var.var_name_ == OB_SV_READ_ONLY) {
|
||||
if (session->get_in_transaction()) {
|
||||
ret = OB_ERR_LOCK_OR_ACTIVE_TRANSACTION;
|
||||
|
||||
LOG_WARN("Can't execute the given command because "
|
||||
"you have active locked tables or an active transaction",
|
||||
K(ret));
|
||||
} else {
|
||||
tenant_schema.set_read_only(value_obj.get_bool());
|
||||
}
|
||||
if (!is_strict_mode(session->get_sql_mode())) {
|
||||
expr_ctx.cast_mode_ = CM_WARN_ON_FAIL;
|
||||
}
|
||||
ObSysVarClassType sys_id = sys_var->get_type();
|
||||
ObString val_str;
|
||||
expr_ctx.calc_buf_ = &ctx.get_allocator(); // make sure use this allocator to keep ObString is valid
|
||||
EXPR_DEFINE_CAST_CTX(expr_ctx, CM_NONE);
|
||||
EXPR_GET_VARCHAR_V2(value_obj, val_str);
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_UNLIKELY(val_str.length() > OB_MAX_SYS_VAR_VAL_LENGTH)) {
|
||||
ret = OB_SIZE_OVERFLOW;
|
||||
LOG_WARN("set sysvar value is overflow",
|
||||
"max length",
|
||||
OB_MAX_SYS_VAR_VAL_LENGTH,
|
||||
"value length",
|
||||
val_str.length(),
|
||||
K(sys_id),
|
||||
K(val_str));
|
||||
} else if (OB_FAIL(sys_var_list.push_back(obrpc::ObSysVarIdValue(sys_id, val_str)))) {
|
||||
LOG_WARN("failed to push back", K(sys_id), K(val_str), K(ret));
|
||||
if (OB_FAIL(expr_gen.generate(*cur_node.value_expr_, sql_expr))) {
|
||||
LOG_WARN("fail to fill sql expression", K(ret));
|
||||
} else if (FALSE_IT(phy_plan.set_regexp_op_count(expr_gen.get_cur_regexp_op_count()))) {
|
||||
} else if (FALSE_IT(phy_plan.set_like_op_count(expr_gen.get_cur_like_op_count()))) {
|
||||
} else if (OB_FAIL(sql_expr.calc(expr_ctx, tmp_row, value_obj))) {
|
||||
LOG_WARN("fail to calc value", K(*cur_node.value_expr_), K(ret));
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
}
|
||||
// second:convert value to dest type
|
||||
uint64_t fake_tenant_id = OB_INVALID_ID;
|
||||
ObSetVar set_var(cur_node.variable_name_,
|
||||
cur_node.set_scope_,
|
||||
cur_node.is_set_default_,
|
||||
fake_tenant_id,
|
||||
*expr_ctx.calc_buf_,
|
||||
*sql_proxy);
|
||||
if (OB_SUCC(ret)) {
|
||||
ObObj out_obj;
|
||||
const bool is_set_stmt = false;
|
||||
if (OB_FAIL(ObVariableSetExecutor::check_and_convert_sys_var(
|
||||
ctx, set_var, *sys_var, value_obj, out_obj, is_set_stmt))) {
|
||||
LOG_WARN("fail to check_and_convert_sys_var", K(cur_node), K(*sys_var), K(value_obj), K(ret));
|
||||
} else if (FALSE_IT(value_obj = out_obj)) {
|
||||
} else if (OB_FAIL(ObVariableSetExecutor::cast_value(
|
||||
ctx, cur_node, fake_tenant_id, *expr_ctx.calc_buf_, *sys_var, value_obj, out_obj))) {
|
||||
LOG_WARN("fail to cast value", K(cur_node), K(*sys_var), K(value_obj), K(ret));
|
||||
} else if (FALSE_IT(value_obj = out_obj)) {
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
}
|
||||
// add variable value into ObCreateTenantArg
|
||||
if (OB_SUCC(ret)) {
|
||||
if (set_var.var_name_ == OB_SV_COLLATION_SERVER || set_var.var_name_ == OB_SV_COLLATION_DATABASE ||
|
||||
set_var.var_name_ == OB_SV_COLLATION_CONNECTION || set_var.var_name_ == OB_SV_CHARACTER_SET_SERVER ||
|
||||
set_var.var_name_ == OB_SV_CHARACTER_SET_DATABASE ||
|
||||
set_var.var_name_ == OB_SV_CHARACTER_SET_CONNECTION) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("collation or charset can not be modify temporarily", K(set_var), K(ret));
|
||||
} else {
|
||||
// read only should also modify tenant_schema
|
||||
if (set_var.var_name_ == OB_SV_READ_ONLY) {
|
||||
if (session->get_in_transaction()) {
|
||||
ret = OB_ERR_LOCK_OR_ACTIVE_TRANSACTION;
|
||||
|
||||
LOG_WARN("Can't execute the given command because "
|
||||
"you have active locked tables or an active transaction",
|
||||
K(ret));
|
||||
} else {
|
||||
tenant_schema.set_read_only(value_obj.get_bool());
|
||||
}
|
||||
}
|
||||
ObSysVarClassType sys_id = sys_var->get_type();
|
||||
ObString val_str;
|
||||
expr_ctx.calc_buf_ = &ctx.get_allocator(); // make sure use this allocator to keep ObString is valid
|
||||
EXPR_DEFINE_CAST_CTX(expr_ctx, CM_NONE);
|
||||
EXPR_GET_VARCHAR_V2(value_obj, val_str);
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_UNLIKELY(val_str.length() > OB_MAX_SYS_VAR_VAL_LENGTH)) {
|
||||
ret = OB_SIZE_OVERFLOW;
|
||||
LOG_WARN("set sysvar value is overflow",
|
||||
"max length",
|
||||
OB_MAX_SYS_VAR_VAL_LENGTH,
|
||||
"value length",
|
||||
val_str.length(),
|
||||
K(sys_id),
|
||||
K(val_str));
|
||||
} else if (OB_FAIL(sys_var_list.push_back(obrpc::ObSysVarIdValue(sys_id, val_str)))) {
|
||||
LOG_WARN("failed to push back", K(sys_id), K(val_str), K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,216 +92,19 @@ int ObVariableSetExecutor::execute(ObExecContext& ctx, ObVariableSetStmt& stmt)
|
||||
} else {
|
||||
expr_ctx.exec_ctx_->set_sql_proxy(sql_proxy);
|
||||
}
|
||||
ObVariableSetStmt::VariableSetNode tmp_node; // just for init node
|
||||
ObVariableSetStmt::VariableNamesSetNode tmp_node; // just for init node
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < stmt.get_variables_size(); ++i) {
|
||||
ObVariableSetStmt::VariableSetNode& node = tmp_node;
|
||||
if (OB_FAIL(stmt.get_variable_node(i, node))) {
|
||||
ObVariableSetStmt::VariableNamesSetNode& var_name_set_node = tmp_node;
|
||||
if (OB_FAIL(stmt.get_variable_node(i, var_name_set_node))) {
|
||||
LOG_WARN("fail to get variable node", K(i), K(ret));
|
||||
} else {
|
||||
ObNewRow tmp_row;
|
||||
ObObj value_obj;
|
||||
ObBasicSysVar* sys_var = NULL;
|
||||
RowDesc row_desc;
|
||||
ObExprGeneratorImpl expr_gen(0, 0, NULL, row_desc);
|
||||
ObSqlExpression sql_expr(ctx.get_allocator(), 0);
|
||||
if (true == node.is_set_default_) {
|
||||
if (false == node.is_system_variable_) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("when reach here, node.is_system_variable_ must be true", K(ret));
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
if (OB_ISNULL(node.value_expr_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("node.value_expr_ is NULL", K(ret));
|
||||
} else {
|
||||
if ((!node.is_system_variable_) || (!is_strict_mode(session->get_sql_mode()))) {
|
||||
expr_ctx.cast_mode_ = CM_WARN_ON_FAIL;
|
||||
} else {
|
||||
}
|
||||
if (OB_FAIL(expr_gen.generate(*node.value_expr_, sql_expr))) {
|
||||
LOG_WARN("fail to fill sql expression", K(ret));
|
||||
} else if (FALSE_IT(phy_plan.set_regexp_op_count(expr_gen.get_cur_regexp_op_count()))) {
|
||||
} else if (FALSE_IT(phy_plan.set_like_op_count(expr_gen.get_cur_like_op_count()))) {
|
||||
} else if (OB_FAIL(sql_expr.calc(expr_ctx, tmp_row, value_obj))) {
|
||||
LOG_WARN("fail to calc value", K(ret), K(*node.value_expr_));
|
||||
} else {
|
||||
}
|
||||
}
|
||||
} else if (var_name_set_node.is_set_variable_) {
|
||||
if (OB_FAIL(set_variable(ctx, session, expr_ctx, sql_proxy, stmt, phy_plan, plan_ctx,
|
||||
var_name_set_node.var_set_node_, ret_ac))) {
|
||||
LOG_WARN("set variable failed", K(ret));
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (false == node.is_system_variable_) {
|
||||
if (OB_FAIL(set_user_variable(value_obj, node.variable_name_, expr_ctx))) {
|
||||
LOG_WARN("set user variable failed", K(ret));
|
||||
}
|
||||
} else {
|
||||
ObSetVar set_var(node.variable_name_,
|
||||
node.set_scope_,
|
||||
node.is_set_default_,
|
||||
stmt.get_actual_tenant_id(),
|
||||
*expr_ctx.calc_buf_,
|
||||
*sql_proxy);
|
||||
ObObj out_obj;
|
||||
const bool is_set_stmt = true;
|
||||
if (OB_FAIL(session->get_sys_variable_by_name(node.variable_name_, sys_var))) {
|
||||
if (OB_ERR_SYS_VARIABLE_UNKNOWN == ret) {
|
||||
// session system variable not found, maybe latest data from proxy,
|
||||
// so search in __all_sys_variable first.
|
||||
const uint64_t tenant_id = session->get_effective_tenant_id();
|
||||
const uint64_t exec_tenant_id = ObSchemaUtils::get_exec_tenant_id(tenant_id);
|
||||
ObSQLClientRetryWeak sql_client_retry_weak(sql_proxy, exec_tenant_id, OB_ALL_SYS_VARIABLE_TID);
|
||||
ObObj tmp_val;
|
||||
ObSqlString sql;
|
||||
SMART_VAR(ObMySQLProxy::MySQLResult, res)
|
||||
{
|
||||
sqlclient::ObMySQLResult* result = NULL;
|
||||
if (OB_FAIL(sql.assign_fmt("select 1 from %s where tenant_id=%lu and name='%.*s';",
|
||||
OB_ALL_SYS_VARIABLE_TNAME,
|
||||
ObSchemaUtils::get_extract_tenant_id(exec_tenant_id, tenant_id),
|
||||
node.variable_name_.length(),
|
||||
node.variable_name_.ptr()))) {
|
||||
LOG_WARN("assign sql string failed", K(ret));
|
||||
} else if (OB_FAIL(sql_client_retry_weak.read(res, exec_tenant_id, sql.ptr()))) {
|
||||
LOG_WARN("execute sql failed", K(sql), K(ret));
|
||||
} else if (OB_ISNULL(result = res.get_result())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to get sql result", K(ret));
|
||||
} else if (OB_FAIL(result->next())) {
|
||||
if (OB_ITER_END == ret) {
|
||||
// not found in inner table, means it is not a system variable
|
||||
ret = OB_ERR_SYS_VARIABLE_UNKNOWN;
|
||||
LOG_USER_ERROR(
|
||||
OB_ERR_SYS_VARIABLE_UNKNOWN, node.variable_name_.length(), node.variable_name_.ptr());
|
||||
} else {
|
||||
LOG_WARN("get result failed", K(ret));
|
||||
}
|
||||
} else {
|
||||
// found in __all_sys_variable, means it's caused by version compatibility.
|
||||
// return OB_SYS_VARS_MAYBE_DIFF_VERSION, set OB_SUCCESS later.
|
||||
ret = OB_SYS_VARS_MAYBE_DIFF_VERSION;
|
||||
LOG_INFO("try to set sys var from new version, ignore it", K(ret), K(node.variable_name_));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG_WARN("fail to get system variable", K(ret), K(node.variable_name_));
|
||||
}
|
||||
} else if (OB_ISNULL(sys_var)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("sys_var is NULL", K(ret), K(node.variable_name_));
|
||||
} else if (!share::is_mysql_mode() && sys_var->is_mysql_only()) {
|
||||
// ignore set mysql only variables in oracle mode
|
||||
} else if (!share::is_oracle_mode() && sys_var->is_oracle_only()) {
|
||||
// ignore set oracle only variables in mysql mode
|
||||
} else {
|
||||
if (OB_FAIL(check_and_convert_sys_var(ctx, set_var, *sys_var, value_obj, out_obj, is_set_stmt))) {
|
||||
LOG_WARN("fail to check", K(ret), K(node), K(*sys_var), K(value_obj));
|
||||
} else if (FALSE_IT(value_obj = out_obj)) {
|
||||
} else if (OB_FAIL(cast_value(ctx,
|
||||
node,
|
||||
stmt.get_actual_tenant_id(),
|
||||
*expr_ctx.calc_buf_,
|
||||
*sys_var,
|
||||
value_obj,
|
||||
out_obj))) {
|
||||
LOG_WARN("fail to cast value", K(ret), K(node), K(*sys_var), K(value_obj));
|
||||
} else if (FALSE_IT(value_obj = out_obj)) {
|
||||
} else if (node.variable_name_ == OB_SV_AUTO_INCREMENT_INCREMENT ||
|
||||
node.variable_name_ == OB_SV_AUTO_INCREMENT_OFFSET) {
|
||||
if (OB_FAIL(process_auto_increment_hook(session->get_sql_mode(), node.variable_name_, value_obj))) {
|
||||
LOG_WARN("fail to process auto increment hook", K(ret));
|
||||
} else {
|
||||
}
|
||||
} else if (node.variable_name_ == OB_SV_LAST_INSERT_ID) {
|
||||
if (OB_FAIL(
|
||||
process_last_insert_id_hook(plan_ctx, session->get_sql_mode(), node.variable_name_, value_obj))) {
|
||||
LOG_WARN("fail to process auto increment hook", K(ret));
|
||||
} else {
|
||||
}
|
||||
} else if (ObSetVar::SET_SCOPE_GLOBAL == node.set_scope_ &&
|
||||
node.variable_name_ == OB_SV_STMT_PARALLEL_DEGREE) {
|
||||
const static int64_t PARALLEL_DEGREE_VALID_VALUE = 1;
|
||||
int64_t parallel_degree_set_val = -1;
|
||||
if (OB_FAIL(value_obj.get_int(parallel_degree_set_val))) {
|
||||
LOG_WARN("fail to get int64_t from value_obj", K(ret), K(value_obj));
|
||||
} else if (PARALLEL_DEGREE_VALID_VALUE != parallel_degree_set_val) {
|
||||
ret = OB_ERR_WRONG_VALUE_FOR_VAR;
|
||||
char buf[32];
|
||||
(void)databuff_printf(buf, 32, "%ld", parallel_degree_set_val);
|
||||
ObString value(buf);
|
||||
LOG_USER_ERROR(OB_ERR_WRONG_VALUE_FOR_VAR,
|
||||
node.variable_name_.length(),
|
||||
node.variable_name_.ptr(),
|
||||
value.length(),
|
||||
value.ptr());
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (ObSetVar::SET_SCOPE_SESSION == node.set_scope_) {
|
||||
// handle autocommit case, must call before update_sys_variable,
|
||||
// because update_sys_variable will change value of ac.
|
||||
if (node.variable_name_ == OB_SV_AUTOCOMMIT) {
|
||||
if (OB_UNLIKELY(OB_SUCCESS != (ret_ac = process_session_autocommit_hook(ctx, value_obj)))) {
|
||||
LOG_WARN("fail to process session autocommit", K(ret), K(ret_ac));
|
||||
if (OB_ERR_WRONG_VALUE_FOR_VAR == ret_ac) {
|
||||
ret = ret_ac;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (set_var.var_name_ == OB_SV_READ_ONLY) {
|
||||
if (session->get_in_transaction()) {
|
||||
ret = OB_ERR_LOCK_OR_ACTIVE_TRANSACTION;
|
||||
|
||||
LOG_WARN("Can't execute the given command because "
|
||||
"you have active locked tables or an active transaction",
|
||||
K(ret));
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (set_var.var_name_ == OB_SV_COMPATIBILITY_MODE) {
|
||||
if (!(OB_SYS_TENANT_ID == session->get_effective_tenant_id()) || !GCONF.in_upgrade_mode()) {
|
||||
ret = OB_OP_NOT_ALLOW;
|
||||
LOG_WARN("Compatibility mode can be changed only under upgrade mode and system tenant",
|
||||
K(ret),
|
||||
K(session->get_effective_tenant_id()));
|
||||
LOG_USER_ERROR(
|
||||
OB_OP_NOT_ALLOW, "Compatibility mode be changed not under upgrade mode and system tenant");
|
||||
} else if (ObSetVar::SET_SCOPE_SESSION != set_var.set_scope_) {
|
||||
ret = OB_OP_NOT_ALLOW;
|
||||
LOG_WARN("Compatibility mode can be changed only under session scope",
|
||||
K(ret),
|
||||
K(session->get_effective_tenant_id()));
|
||||
LOG_USER_ERROR(OB_OP_NOT_ALLOW, "Compatibility mode be changed not in session scope");
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret) && set_var.set_scope_ == ObSetVar::SET_SCOPE_GLOBAL) {
|
||||
if (OB_FAIL(update_global_variables(ctx, stmt, set_var, value_obj))) {
|
||||
LOG_WARN("failed to update global variables", K(ret));
|
||||
} else {
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && set_var.set_scope_ == ObSetVar::SET_SCOPE_SESSION) {
|
||||
if (OB_FAIL(sys_var->session_update(ctx, set_var, value_obj))) {
|
||||
LOG_WARN("fail to update", K(ret), K(*sys_var), K(set_var), K(value_obj));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(sys_var->update(ctx, set_var, value_obj))) {
|
||||
LOG_WARN("update sys var state failed", K(ret), K(set_var));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (OB_FAIL(set_names_charset(ctx, var_name_set_node.names_set_node_))) {
|
||||
LOG_WARN("set names or charset failed", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SYS_VARS_MAYBE_DIFF_VERSION == ret) {
|
||||
@ -315,6 +118,224 @@ int ObVariableSetExecutor::execute(ObExecContext& ctx, ObVariableSetStmt& stmt)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObVariableSetExecutor::set_variable(ObExecContext& ctx, ObSQLSessionInfo* session,
|
||||
ObExprCtx &expr_ctx,
|
||||
ObMySQLProxy* sql_proxy,
|
||||
ObVariableSetStmt& stmt,
|
||||
ObPhysicalPlan& phy_plan,
|
||||
ObPhysicalPlanCtx* plan_ctx,
|
||||
const ObVariableSetStmt::VariableSetNode& node,
|
||||
int& ret_ac)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObNewRow tmp_row;
|
||||
ObObj value_obj;
|
||||
ObBasicSysVar* sys_var = NULL;
|
||||
RowDesc row_desc;
|
||||
ObExprGeneratorImpl expr_gen(0, 0, NULL, row_desc);
|
||||
ObSqlExpression sql_expr(ctx.get_allocator(), 0);
|
||||
if (true == node.is_set_default_) {
|
||||
if (false == node.is_system_variable_) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("when reach here, node.is_system_variable_ must be true", K(ret));
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
if (OB_ISNULL(node.value_expr_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("node.value_expr_ is NULL", K(ret));
|
||||
} else {
|
||||
if ((!node.is_system_variable_) || (!is_strict_mode(session->get_sql_mode()))) {
|
||||
expr_ctx.cast_mode_ = CM_WARN_ON_FAIL;
|
||||
} else {
|
||||
}
|
||||
if (OB_FAIL(expr_gen.generate(*node.value_expr_, sql_expr))) {
|
||||
LOG_WARN("fail to fill sql expression", K(ret));
|
||||
} else if (FALSE_IT(phy_plan.set_regexp_op_count(expr_gen.get_cur_regexp_op_count()))) {
|
||||
} else if (FALSE_IT(phy_plan.set_like_op_count(expr_gen.get_cur_like_op_count()))) {
|
||||
} else if (OB_FAIL(sql_expr.calc(expr_ctx, tmp_row, value_obj))) {
|
||||
LOG_WARN("fail to calc value", K(ret), K(*node.value_expr_));
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (false == node.is_system_variable_) {
|
||||
if (OB_FAIL(set_user_variable(value_obj, node.variable_name_, expr_ctx))) {
|
||||
LOG_WARN("set user variable failed", K(ret));
|
||||
}
|
||||
} else {
|
||||
ObSetVar set_var(node.variable_name_,
|
||||
node.set_scope_,
|
||||
node.is_set_default_,
|
||||
stmt.get_actual_tenant_id(),
|
||||
*expr_ctx.calc_buf_,
|
||||
*sql_proxy);
|
||||
ObObj out_obj;
|
||||
const bool is_set_stmt = true;
|
||||
if (OB_FAIL(session->get_sys_variable_by_name(node.variable_name_, sys_var))) {
|
||||
if (OB_ERR_SYS_VARIABLE_UNKNOWN == ret) {
|
||||
// session system variable not found, maybe latest data from proxy,
|
||||
// so search in __all_sys_variable first.
|
||||
const uint64_t tenant_id = session->get_effective_tenant_id();
|
||||
const uint64_t exec_tenant_id = ObSchemaUtils::get_exec_tenant_id(tenant_id);
|
||||
ObSQLClientRetryWeak sql_client_retry_weak(sql_proxy, exec_tenant_id, OB_ALL_SYS_VARIABLE_TID);
|
||||
ObObj tmp_val;
|
||||
ObSqlString sql;
|
||||
SMART_VAR(ObMySQLProxy::MySQLResult, res)
|
||||
{
|
||||
sqlclient::ObMySQLResult* result = NULL;
|
||||
if (OB_FAIL(sql.assign_fmt("select 1 from %s where tenant_id=%lu and name='%.*s';",
|
||||
OB_ALL_SYS_VARIABLE_TNAME,
|
||||
ObSchemaUtils::get_extract_tenant_id(exec_tenant_id, tenant_id),
|
||||
node.variable_name_.length(),
|
||||
node.variable_name_.ptr()))) {
|
||||
LOG_WARN("assign sql string failed", K(ret));
|
||||
} else if (OB_FAIL(sql_client_retry_weak.read(res, exec_tenant_id, sql.ptr()))) {
|
||||
LOG_WARN("execute sql failed", K(sql), K(ret));
|
||||
} else if (OB_ISNULL(result = res.get_result())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to get sql result", K(ret));
|
||||
} else if (OB_FAIL(result->next())) {
|
||||
if (OB_ITER_END == ret) {
|
||||
// not found in inner table, means it is not a system variable
|
||||
ret = OB_ERR_SYS_VARIABLE_UNKNOWN;
|
||||
LOG_USER_ERROR(
|
||||
OB_ERR_SYS_VARIABLE_UNKNOWN, node.variable_name_.length(), node.variable_name_.ptr());
|
||||
} else {
|
||||
LOG_WARN("get result failed", K(ret));
|
||||
}
|
||||
} else {
|
||||
// found in __all_sys_variable, means it's caused by version compatibility.
|
||||
// return OB_SYS_VARS_MAYBE_DIFF_VERSION, set OB_SUCCESS later.
|
||||
ret = OB_SYS_VARS_MAYBE_DIFF_VERSION;
|
||||
LOG_INFO("try to set sys var from new version, ignore it", K(ret), K(node.variable_name_));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG_WARN("fail to get system variable", K(ret), K(node.variable_name_));
|
||||
}
|
||||
} else if (OB_ISNULL(sys_var)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("sys_var is NULL", K(ret), K(node.variable_name_));
|
||||
} else if (!share::is_mysql_mode() && sys_var->is_mysql_only()) {
|
||||
// ignore set mysql only variables in oracle mode
|
||||
} else if (!share::is_oracle_mode() && sys_var->is_oracle_only()) {
|
||||
// ignore set oracle only variables in mysql mode
|
||||
} else {
|
||||
if (OB_FAIL(check_and_convert_sys_var(ctx, set_var, *sys_var, value_obj, out_obj, is_set_stmt))) {
|
||||
LOG_WARN("fail to check", K(ret), K(node), K(*sys_var), K(value_obj));
|
||||
} else if (FALSE_IT(value_obj = out_obj)) {
|
||||
} else if (OB_FAIL(cast_value(ctx,
|
||||
node,
|
||||
stmt.get_actual_tenant_id(),
|
||||
*expr_ctx.calc_buf_,
|
||||
*sys_var,
|
||||
value_obj,
|
||||
out_obj))) {
|
||||
LOG_WARN("fail to cast value", K(ret), K(node), K(*sys_var), K(value_obj));
|
||||
} else if (FALSE_IT(value_obj = out_obj)) {
|
||||
} else if (node.variable_name_ == OB_SV_AUTO_INCREMENT_INCREMENT ||
|
||||
node.variable_name_ == OB_SV_AUTO_INCREMENT_OFFSET) {
|
||||
if (OB_FAIL(process_auto_increment_hook(session->get_sql_mode(), node.variable_name_, value_obj))) {
|
||||
LOG_WARN("fail to process auto increment hook", K(ret));
|
||||
} else {
|
||||
}
|
||||
} else if (node.variable_name_ == OB_SV_LAST_INSERT_ID) {
|
||||
if (OB_FAIL(
|
||||
process_last_insert_id_hook(plan_ctx, session->get_sql_mode(), node.variable_name_, value_obj))) {
|
||||
LOG_WARN("fail to process auto increment hook", K(ret));
|
||||
} else {
|
||||
}
|
||||
} else if (ObSetVar::SET_SCOPE_GLOBAL == node.set_scope_ &&
|
||||
node.variable_name_ == OB_SV_STMT_PARALLEL_DEGREE) {
|
||||
const static int64_t PARALLEL_DEGREE_VALID_VALUE = 1;
|
||||
int64_t parallel_degree_set_val = -1;
|
||||
if (OB_FAIL(value_obj.get_int(parallel_degree_set_val))) {
|
||||
LOG_WARN("fail to get int64_t from value_obj", K(ret), K(value_obj));
|
||||
} else if (PARALLEL_DEGREE_VALID_VALUE != parallel_degree_set_val) {
|
||||
ret = OB_ERR_WRONG_VALUE_FOR_VAR;
|
||||
char buf[32];
|
||||
(void)databuff_printf(buf, 32, "%ld", parallel_degree_set_val);
|
||||
ObString value(buf);
|
||||
LOG_USER_ERROR(OB_ERR_WRONG_VALUE_FOR_VAR,
|
||||
node.variable_name_.length(),
|
||||
node.variable_name_.ptr(),
|
||||
value.length(),
|
||||
value.ptr());
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (ObSetVar::SET_SCOPE_SESSION == node.set_scope_) {
|
||||
// handle autocommit case, must call before update_sys_variable,
|
||||
// because update_sys_variable will change value of ac.
|
||||
if (node.variable_name_ == OB_SV_AUTOCOMMIT) {
|
||||
if (OB_UNLIKELY(OB_SUCCESS != (ret_ac = process_session_autocommit_hook(ctx, value_obj)))) {
|
||||
LOG_WARN("fail to process session autocommit", K(ret), K(ret_ac));
|
||||
if (OB_ERR_WRONG_VALUE_FOR_VAR == ret_ac) {
|
||||
ret = ret_ac;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (set_var.var_name_ == OB_SV_READ_ONLY) {
|
||||
if (session->get_in_transaction()) {
|
||||
ret = OB_ERR_LOCK_OR_ACTIVE_TRANSACTION;
|
||||
|
||||
LOG_WARN("Can't execute the given command because "
|
||||
"you have active locked tables or an active transaction",
|
||||
K(ret));
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (set_var.var_name_ == OB_SV_COMPATIBILITY_MODE) {
|
||||
if (!(OB_SYS_TENANT_ID == session->get_effective_tenant_id()) || !GCONF.in_upgrade_mode()) {
|
||||
ret = OB_OP_NOT_ALLOW;
|
||||
LOG_WARN("Compatibility mode can be changed only under upgrade mode and system tenant",
|
||||
K(ret),
|
||||
K(session->get_effective_tenant_id()));
|
||||
LOG_USER_ERROR(
|
||||
OB_OP_NOT_ALLOW, "Compatibility mode be changed not under upgrade mode and system tenant");
|
||||
} else if (ObSetVar::SET_SCOPE_SESSION != set_var.set_scope_) {
|
||||
ret = OB_OP_NOT_ALLOW;
|
||||
LOG_WARN("Compatibility mode can be changed only under session scope",
|
||||
K(ret),
|
||||
K(session->get_effective_tenant_id()));
|
||||
LOG_USER_ERROR(OB_OP_NOT_ALLOW, "Compatibility mode be changed not in session scope");
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret) && set_var.set_scope_ == ObSetVar::SET_SCOPE_GLOBAL) {
|
||||
if (OB_FAIL(update_global_variables(ctx, stmt, set_var, value_obj))) {
|
||||
LOG_WARN("failed to update global variables", K(ret));
|
||||
} else {
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && set_var.set_scope_ == ObSetVar::SET_SCOPE_SESSION) {
|
||||
if (OB_FAIL(sys_var->session_update(ctx, set_var, value_obj))) {
|
||||
LOG_WARN("fail to update", K(ret), K(*sys_var), K(set_var), K(value_obj));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(sys_var->update(ctx, set_var, value_obj))) {
|
||||
LOG_WARN("update sys var state failed", K(ret), K(set_var));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObVariableSetExecutor::set_user_variable(const ObObj& val, const ObString& variable_name, const ObExprCtx& expr_ctx)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -865,6 +886,164 @@ int ObVariableSetExecutor::switch_to_session_variable(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObVariableSetExecutor::set_names_charset(ObExecContext& ctx,
|
||||
const ObVariableSetStmt::NamesSetNode& names_set_node)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* session = NULL;
|
||||
if (OB_ISNULL(session = ctx.get_my_session())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(ERROR, "session is NULL", K(ret), K(ctx));
|
||||
} else {
|
||||
ObString charset;
|
||||
if (names_set_node.is_default_charset_) {
|
||||
// Compatible with mysql, take the global character_set_client value
|
||||
if (OB_FAIL(get_global_sys_var_character_set_client(ctx, charset))) {
|
||||
SQL_ENG_LOG(WARN, "fail to get global character_set_client", K(ret));
|
||||
}
|
||||
} else {
|
||||
charset = names_set_node.charset_;
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
ObString collation = names_set_node.collation_;
|
||||
ObCollationType collation_type = CS_TYPE_INVALID;
|
||||
ObCharsetType cs_type = ObCharset::charset_type(charset);
|
||||
if (CHARSET_INVALID == cs_type) {
|
||||
ret = OB_ERR_UNKNOWN_CHARSET;
|
||||
LOG_USER_ERROR(OB_ERR_UNKNOWN_CHARSET, charset.length(), charset.ptr());
|
||||
} else {
|
||||
charset = ObString::make_string(ObCharset::charset_name(cs_type));
|
||||
if (!names_set_node.is_default_collation_) {
|
||||
collation_type = ObCharset::collation_type(collation);
|
||||
if (CS_TYPE_INVALID == collation_type) {
|
||||
ret = OB_ERR_UNKNOWN_COLLATION;
|
||||
LOG_USER_ERROR(OB_ERR_UNKNOWN_COLLATION, collation.length(), collation.ptr());
|
||||
} else if (!ObCharset::is_valid_collation(cs_type, collation_type)) {
|
||||
ret = OB_ERR_COLLATION_MISMATCH;
|
||||
LOG_USER_ERROR(
|
||||
OB_ERR_COLLATION_MISMATCH, collation.length(), collation.ptr(), charset.length(), charset.ptr());
|
||||
} else {
|
||||
collation = ObString::make_string(ObCharset::collation_name(collation_type));
|
||||
}
|
||||
} else {
|
||||
// the use default collation of this charset
|
||||
collation_type = ObCharset::get_default_collation(cs_type);
|
||||
collation = ObString::make_string(ObCharset::collation_name(collation_type));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (!ObCharset::is_valid_connection_collation(collation_type)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
SQL_ENG_LOG(WARN,
|
||||
"collation type not supported",
|
||||
"charset type",
|
||||
ObCharset::charset_name(cs_type),
|
||||
"collation type",
|
||||
ObCharset::collation_name(collation_type));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (names_set_node.is_set_names_) {
|
||||
// SET NAMES
|
||||
ObCollationType cs_coll_type = ObCharset::get_default_collation(ObCharset::charset_type(charset));
|
||||
ObCollationType coll_type = ObCharset::collation_type(collation);
|
||||
if (CS_TYPE_INVALID == cs_coll_type || CS_TYPE_INVALID == coll_type) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(ERROR, "cs coll type or coll type is invalid", K(ret), K(cs_coll_type), K(coll_type));
|
||||
} else if (OB_FAIL(session->update_sys_variable(
|
||||
SYS_VAR_CHARACTER_SET_CLIENT, static_cast<int64_t>(cs_coll_type)))) {
|
||||
SQL_ENG_LOG(WARN, "failed to update sys var", K(ret));
|
||||
} else if (OB_FAIL(session->update_sys_variable(
|
||||
SYS_VAR_CHARACTER_SET_RESULTS, static_cast<int64_t>(cs_coll_type)))) {
|
||||
SQL_ENG_LOG(WARN, "failed to update sys var", K(ret));
|
||||
} else if (OB_FAIL(session->update_sys_variable(
|
||||
SYS_VAR_CHARACTER_SET_CONNECTION, static_cast<int64_t>(cs_coll_type)))) {
|
||||
SQL_ENG_LOG(WARN, "failed to update sys var", K(ret));
|
||||
} else if (OB_FAIL(
|
||||
session->update_sys_variable(SYS_VAR_COLLATION_CONNECTION, static_cast<int64_t>(coll_type)))) {
|
||||
SQL_ENG_LOG(WARN, "failed to update sys var", K(ret));
|
||||
}
|
||||
} else {
|
||||
// SET CHARACTER SET
|
||||
ObObj database_charset;
|
||||
ObObj database_collation;
|
||||
ObCollationType cs_coll_type = ObCharset::get_default_collation(ObCharset::charset_type(charset));
|
||||
if (OB_FAIL(session->get_sys_variable(SYS_VAR_CHARACTER_SET_DATABASE, database_charset))) {
|
||||
} else if (OB_FAIL(session->get_sys_variable(SYS_VAR_COLLATION_DATABASE, database_collation))) {
|
||||
} else {
|
||||
ObCollationType collation_connection = static_cast<ObCollationType>(database_collation.get_int());
|
||||
ObCharsetType charset_connection = ObCharset::charset_type_by_coll(collation_connection);
|
||||
if (!ObCharset::is_valid_connection_collation(collation_connection)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
SQL_ENG_LOG(WARN,
|
||||
"connection collation type not supported",
|
||||
"charset type",
|
||||
ObCharset::charset_name(charset_connection),
|
||||
"collation type",
|
||||
ObCharset::collation_name(collation_connection));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(
|
||||
session->update_sys_variable(SYS_VAR_CHARACTER_SET_CLIENT, static_cast<int64_t>(cs_coll_type)))) {
|
||||
SQL_EXE_LOG(WARN, "failed to update sys var", K(ret));
|
||||
} else if (OB_FAIL(session->update_sys_variable(
|
||||
SYS_VAR_CHARACTER_SET_RESULTS, static_cast<int64_t>(cs_coll_type)))) {
|
||||
SQL_EXE_LOG(WARN, "failed to update sys var", K(ret));
|
||||
} else if (OB_FAIL(session->update_sys_variable(SYS_VAR_CHARACTER_SET_CONNECTION, database_charset))) {
|
||||
SQL_EXE_LOG(WARN, "failed to update sys var", K(ret));
|
||||
} else if (OB_FAIL(session->update_sys_variable(SYS_VAR_COLLATION_CONNECTION, database_collation))) {
|
||||
SQL_EXE_LOG(WARN, "failed to update sys var", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObVariableSetExecutor::get_global_sys_var_character_set_client(
|
||||
ObExecContext& ctx, ObString& character_set_client) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* session = NULL;
|
||||
ObIAllocator& allocator = ctx.get_allocator();
|
||||
ObSchemaGetterGuard schema_guard;
|
||||
const ObSysVarSchema* var_schema = NULL;
|
||||
ObObj value;
|
||||
if (NULL == (session = ctx.get_my_session())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(ERROR, "session is NULL", K(ret), K(ctx));
|
||||
} else if (OB_ISNULL(GCTX.schema_service_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(ERROR, "schema service is null");
|
||||
} else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard(session->get_effective_tenant_id(), schema_guard))) {
|
||||
SQL_ENG_LOG(WARN, "get schema guard failed", K(ret));
|
||||
} else if (OB_FAIL(schema_guard.get_tenant_system_variable(
|
||||
session->get_effective_tenant_id(), SYS_VAR_CHARACTER_SET_CLIENT, var_schema))) {
|
||||
SQL_ENG_LOG(WARN, "get tenant system variable failed", K(ret));
|
||||
} else if (OB_ISNULL(var_schema)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "var_schema is null");
|
||||
} else if (OB_FAIL(var_schema->get_value(&allocator, ObBasicSessionInfo::create_dtc_params(session), value))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "get value from var_schema failed", K(ret), K(*var_schema));
|
||||
} else if (ObIntType != value.get_type()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(ERROR, "sys var character_set_client's type must be ObIntType", K(ret), K(value));
|
||||
} else {
|
||||
ObCollationType coll_type = static_cast<ObCollationType>(value.get_int());
|
||||
if (!ObCharset::is_valid_collation(coll_type)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "invalid collation type", K(ret), K(coll_type));
|
||||
} else {
|
||||
const char* cs_name_ptr = ObCharset::charset_name(coll_type);
|
||||
character_set_client = ObString(cs_name_ptr);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#undef DEFINE_CAST_CTX
|
||||
|
||||
} // namespace sql
|
||||
|
@ -51,6 +51,12 @@ private:
|
||||
|
||||
int update_global_variables(
|
||||
ObExecContext& ctx, ObDDLStmt& stmt, const share::ObSetVar& set_var, const common::ObObj& value_obj);
|
||||
int set_variable(ObExecContext& ctx, ObSQLSessionInfo* session, ObExprCtx &expr_ctx,
|
||||
ObMySQLProxy* sql_proxy, ObVariableSetStmt& stmt,
|
||||
ObPhysicalPlan& phy_plan, ObPhysicalPlanCtx* plan_ctx,
|
||||
const ObVariableSetStmt::VariableSetNode& node, int& ret_ac);
|
||||
int set_names_charset(ObExecContext& ctx,const ObVariableSetStmt::NamesSetNode& names_set_node);
|
||||
int get_global_sys_var_character_set_client(ObExecContext& ctx, common::ObString& character_set_client) const;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObVariableSetExecutor);
|
||||
|
@ -88,7 +88,6 @@
|
||||
#include "sql/engine/cmd/ob_dcl_executor.h"
|
||||
#include "sql/engine/cmd/ob_tcl_executor.h"
|
||||
#include "sql/engine/cmd/ob_tenant_executor.h"
|
||||
#include "sql/engine/cmd/ob_set_names_executor.h"
|
||||
#include "sql/engine/cmd/ob_alter_system_executor.h"
|
||||
#include "sql/engine/cmd/ob_set_password_executor.h"
|
||||
#include "sql/engine/cmd/ob_tablegroup_executor.h"
|
||||
@ -542,11 +541,6 @@ int ObCmdExecutor::execute(ObExecContext& ctx, ObICmd& cmd)
|
||||
DEFINE_EXECUTE_CMD(ObCancelTaskStmt, ObCancelTaskExecutor);
|
||||
break;
|
||||
}
|
||||
case stmt::T_SET_NAMES: {
|
||||
DEFINE_EXECUTE_CMD(ObSetNamesStmt, ObSetNamesExecutor);
|
||||
sql_text = ObString::make_empty_string(); // do not record
|
||||
break;
|
||||
}
|
||||
case stmt::T_LOAD_DATA: {
|
||||
DEFINE_EXECUTE_CMD(ObLoadDataStmt, ObLoadDataExecutor);
|
||||
break;
|
||||
|
@ -1482,9 +1482,7 @@ bool ObSQLUtils::is_readonly_stmt(ParseResult& result)
|
||||
T_SHOW_PARAMETERS == type || T_SHOW_INDEXES == type || T_SHOW_PROCESSLIST == type ||
|
||||
T_SHOW_TABLEGROUPS == type || T_USE_DATABASE == type || T_TRANSACTION == type || T_BEGIN == type ||
|
||||
T_COMMIT == type || T_ROLLBACK == type || T_VARIABLE_SET == type ||
|
||||
T_SET_NAMES == type // read only not restrict it
|
||||
|| T_SET_CHARSET == type // read only not restrict it
|
||||
|| T_SHOW_RECYCLEBIN == type || T_SHOW_TENANT == type || T_SHOW_RESTORE_PREVIEW == type) {
|
||||
T_SHOW_RECYCLEBIN == type || T_SHOW_TENANT == type || T_SHOW_RESTORE_PREVIEW == type) {
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
@ -401,7 +401,6 @@ END_P SET_VAR DELIMITER
|
||||
%type <node> zone_action upgrade_action
|
||||
%type <node> opt_index_name opt_key_or_index opt_index_options opt_primary opt_all
|
||||
%type <node> charset_key database_key charset_name charset_name_or_default collation_name databases_or_schemas trans_param_name trans_param_value
|
||||
%type <node> set_names_stmt set_charset_stmt
|
||||
%type <node> charset_introducer complex_string_literal literal number_literal now_or_signed_literal signed_literal
|
||||
%type <node> create_tablegroup_stmt drop_tablegroup_stmt alter_tablegroup_stmt default_tablegroup
|
||||
%type <node> set_transaction_stmt transaction_characteristics transaction_access_mode isolation_level
|
||||
@ -520,8 +519,6 @@ stmt:
|
||||
| create_resource_stmt { $$ = $1; check_question_mark($$, result); }
|
||||
| alter_resource_stmt { $$ = $1; check_question_mark($$, result); }
|
||||
| drop_resource_stmt { $$ = $1; check_question_mark($$, result); }
|
||||
| set_names_stmt { $$ = $1; check_question_mark($$, result); }
|
||||
| set_charset_stmt { $$ = $1; check_question_mark($$, result); }
|
||||
| create_tablegroup_stmt { $$ = $1; check_question_mark($$, result); }
|
||||
| drop_tablegroup_stmt { $$ = $1; check_question_mark($$, result); }
|
||||
| alter_tablegroup_stmt { $$ = $1; check_question_mark($$, result); }
|
||||
@ -10718,6 +10715,15 @@ USER_VARIABLE to_or_eq expr
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_VAR_VAL, 2, $1, $3);
|
||||
$$->value_ = 2;
|
||||
}
|
||||
| NAMES charset_name_or_default opt_collation
|
||||
{
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_SET_NAMES, 2, $2, $3);
|
||||
}
|
||||
| charset_key charset_name_or_default
|
||||
{
|
||||
(void)($1);
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_SET_CHARSET, 1, $2);
|
||||
}
|
||||
;
|
||||
|
||||
sys_var_and_val:
|
||||
@ -13022,23 +13028,6 @@ BEGI
|
||||
}
|
||||
;
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
/* SET NAMES 'charset_name' [COLLATE 'collation_name'] */
|
||||
set_names_stmt:
|
||||
SET NAMES charset_name_or_default opt_collation
|
||||
{
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_SET_NAMES, 2, $3, $4);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
/* SET CHARACTER SET charset_name */
|
||||
set_charset_stmt:
|
||||
SET charset_key charset_name_or_default
|
||||
{
|
||||
(void)($2);
|
||||
malloc_non_terminal_node($$, result->malloc_pool_, T_SET_CHARSET, 1, $3);
|
||||
};
|
||||
|
||||
//////////////////////////////
|
||||
set_transaction_stmt:
|
||||
SET TRANSACTION transaction_characteristics
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -371,6 +371,7 @@ const char* get_type_name(int type)
|
||||
case T_FUN_SYS_QUARTER : return "T_FUN_SYS_QUARTER";
|
||||
case T_FUN_SYS_BIT_LENGTH : return "T_FUN_SYS_BIT_LENGTH";
|
||||
case T_FUN_SYS_PI : return "T_FUN_SYS_PI";
|
||||
case T_FUN_SYS_DEGREES : return "T_FUN_SYS_DEGREES";
|
||||
case T_FUN_SYS_EXPORT_SET : return "T_FUN_SYS_EXPORT_SET";
|
||||
case T_FUN_SYS_INET6NTOA : return "T_FUN_SYS_INET6NTOA";
|
||||
case T_FUN_SYS_INET6ATON : return "T_FUN_SYS_INET6ATON";
|
||||
@ -379,8 +380,8 @@ const char* get_type_name(int type)
|
||||
case T_FUN_SYS_IS_IPV4_MAPPED : return "T_FUN_SYS_IS_IPV4_MAPPED";
|
||||
case T_FUN_SYS_IS_IPV4_COMPAT : return "T_FUN_SYS_IS_IPV4_COMPAT";
|
||||
case T_FUN_SYS_INETATON : return "T_FUN_SYS_INETATON";
|
||||
case T_FUN_SYS_CRC32 : return "T_FUN_SYS_CRC32";
|
||||
case T_FUN_SYS_WEIGHT_STRING : return "T_FUN_SYS_WEIGHT_STRING";
|
||||
case T_FUN_SYS_CRC32 : return "T_FUN_SYS_CRC32";
|
||||
case T_MYSQL_ONLY_SYS_MAX_OP : return "T_MYSQL_ONLY_SYS_MAX_OP";
|
||||
case T_FUN_SYS_CONNECT_BY_PATH : return "T_FUN_SYS_CONNECT_BY_PATH";
|
||||
case T_FUN_SYS_SYSTIMESTAMP : return "T_FUN_SYS_SYSTIMESTAMP";
|
||||
|
@ -46,7 +46,6 @@
|
||||
#include "sql/resolver/ddl/ob_truncate_table_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_rename_table_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_create_table_like_stmt.h"
|
||||
#include "sql/resolver/cmd/ob_set_names_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_create_tablegroup_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_drop_tablegroup_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_alter_tablegroup_stmt.h"
|
||||
|
@ -3570,7 +3570,8 @@ int ObAlterSystemSetResolver::resolve(const ParseNode& parse_tree)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && OB_FAIL(variable_set_stmt->add_variable_node(var_node))) {
|
||||
if (OB_SUCC(ret) && OB_FAIL(variable_set_stmt->add_variable_node(
|
||||
ObVariableSetStmt::make_variable_name_node(var_node)))) {
|
||||
LOG_WARN("Add set entry failed", K(ret));
|
||||
}
|
||||
}
|
||||
|
@ -1,92 +0,0 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "sql/resolver/cmd/ob_set_names_resolver.h"
|
||||
#include "sql/resolver/cmd/ob_set_names_stmt.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace oceanbase::common;
|
||||
namespace sql {
|
||||
ObSetNamesResolver::ObSetNamesResolver(ObResolverParams& params) : ObCMDResolver(params)
|
||||
{}
|
||||
|
||||
ObSetNamesResolver::~ObSetNamesResolver()
|
||||
{}
|
||||
|
||||
int ObSetNamesResolver::resolve(const ParseNode& parse_tree)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (T_SET_NAMES != parse_tree.type_ && T_SET_CHARSET != parse_tree.type_) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
SQL_RESV_LOG(WARN, "create stmt failed", K(ret));
|
||||
} else if (OB_ISNULL(parse_tree.children_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_RESV_LOG(WARN, "parse_tree.children_ is null.", K(ret));
|
||||
} else if (OB_ISNULL(parse_tree.children_[0])) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_RESV_LOG(WARN, "parse_tree.children_[0] is null.", K(ret));
|
||||
} else {
|
||||
ObSetNamesStmt* stmt = NULL;
|
||||
if (OB_ISNULL(stmt = create_stmt<ObSetNamesStmt>())) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
SQL_RESV_LOG(ERROR, "create stmt failed", K(ret));
|
||||
} else {
|
||||
if (T_SET_NAMES == parse_tree.type_) {
|
||||
// SET NAMES
|
||||
stmt->set_is_set_names(true);
|
||||
if (T_DEFAULT == parse_tree.children_[0]->type_) {
|
||||
stmt->set_is_default_charset(true);
|
||||
} else {
|
||||
ObString charset;
|
||||
charset.assign_ptr(
|
||||
parse_tree.children_[0]->str_value_, static_cast<int32_t>(parse_tree.children_[0]->str_len_));
|
||||
if (0 == charset.case_compare("utf16")) {
|
||||
ret = OB_ERR_WRONG_VALUE_FOR_VAR;
|
||||
LOG_USER_ERROR(OB_ERR_WRONG_VALUE_FOR_VAR,
|
||||
static_cast<int>(strlen("character_set_client")),
|
||||
"character_set_client",
|
||||
charset.length(),
|
||||
charset.ptr());
|
||||
} else {
|
||||
stmt->set_charset(charset);
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (NULL == parse_tree.children_[1]) {
|
||||
// do nothing
|
||||
} else if (T_DEFAULT == parse_tree.children_[1]->type_) {
|
||||
stmt->set_is_default_collation(true);
|
||||
} else {
|
||||
ObString collation;
|
||||
collation.assign_ptr(
|
||||
parse_tree.children_[1]->str_value_, static_cast<int32_t>(parse_tree.children_[1]->str_len_));
|
||||
stmt->set_collation(collation);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// SET CHARACTER SET
|
||||
stmt->set_is_set_names(false);
|
||||
if (T_DEFAULT == parse_tree.children_[0]->type_) {
|
||||
stmt->set_is_default_charset(true);
|
||||
} else {
|
||||
ObString charset;
|
||||
charset.assign_ptr(
|
||||
parse_tree.children_[0]->str_value_, static_cast<int32_t>(parse_tree.children_[0]->str_len_));
|
||||
stmt->set_charset(charset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
@ -1,34 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef _OB_SET_NAMES_RESOLVER_H
|
||||
#define _OB_SET_NAMES_RESOLVER_H
|
||||
#include "sql/resolver/cmd/ob_cmd_resolver.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
// resolver for both SET NAMES and SET CHARSET
|
||||
class ObSetNamesResolver : public ObCMDResolver {
|
||||
public:
|
||||
explicit ObSetNamesResolver(ObResolverParams& params);
|
||||
virtual ~ObSetNamesResolver();
|
||||
|
||||
virtual int resolve(const ParseNode& parse_tree);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObSetNamesResolver);
|
||||
};
|
||||
|
||||
} // end namespace sql
|
||||
} // end namespace oceanbase
|
||||
|
||||
#endif // _OB_SET_NAMES_RESOLVER_H
|
@ -1,94 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef _OB_SET_NAMES_STMT_H
|
||||
#define _OB_SET_NAMES_STMT_H
|
||||
#include "lib/string/ob_string.h"
|
||||
#include "sql/resolver/cmd/ob_cmd_stmt.h"
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
// statement for both SET NAMES and SET CHARSET
|
||||
class ObSetNamesStmt : public ObCMDStmt {
|
||||
public:
|
||||
ObSetNamesStmt()
|
||||
: ObCMDStmt(stmt::T_SET_NAMES), is_set_names_(true), is_default_charset_(false), is_default_collation_(false)
|
||||
{}
|
||||
virtual ~ObSetNamesStmt()
|
||||
{}
|
||||
|
||||
bool is_set_names() const
|
||||
{
|
||||
return this->is_set_names_;
|
||||
}
|
||||
void set_is_set_names(bool is_set_names)
|
||||
{
|
||||
this->is_set_names_ = is_set_names;
|
||||
}
|
||||
|
||||
bool is_default_charset() const
|
||||
{
|
||||
return is_default_charset_;
|
||||
}
|
||||
void set_is_default_charset(bool is_default)
|
||||
{
|
||||
is_default_charset_ = is_default;
|
||||
}
|
||||
|
||||
bool is_default_collation() const
|
||||
{
|
||||
return is_default_collation_;
|
||||
}
|
||||
void set_is_default_collation(bool is_default)
|
||||
{
|
||||
is_default_collation_ = is_default;
|
||||
}
|
||||
|
||||
const common::ObString& get_charset() const
|
||||
{
|
||||
return this->charset_;
|
||||
}
|
||||
void set_charset(const common::ObString& charset)
|
||||
{
|
||||
this->charset_ = charset;
|
||||
}
|
||||
|
||||
const common::ObString& get_collation() const
|
||||
{
|
||||
return this->collation_;
|
||||
}
|
||||
void set_collation(const common::ObString& collation)
|
||||
{
|
||||
this->collation_ = collation;
|
||||
}
|
||||
TO_STRING_KV(N_STMT_TYPE, ((int)stmt_type_), K_(is_set_names), K_(is_default_charset), K_(is_default_collation),
|
||||
K_(charset), K_(collation));
|
||||
|
||||
private:
|
||||
// types and constants
|
||||
private:
|
||||
// function members
|
||||
private:
|
||||
// data members
|
||||
bool is_set_names_; // SET NAMES or SET CHARSET?
|
||||
bool is_default_charset_;
|
||||
bool is_default_collation_;
|
||||
common::ObString charset_;
|
||||
common::ObString collation_;
|
||||
|
||||
// disallow copy
|
||||
DISALLOW_COPY_AND_ASSIGN(ObSetNamesStmt);
|
||||
};
|
||||
|
||||
} // end namespace sql
|
||||
} // end namespace oceanbase
|
||||
|
||||
#endif // _OB_SET_NAMES_STMT_H
|
@ -91,17 +91,18 @@ int ObSetTransactionResolver::resolve(const ParseNode& parse_tree)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret) && set_isolation_level) {
|
||||
if (OB_FAIL(build_isolation_expr(isolation_var_node.value_expr_, isolation_level))) {
|
||||
LOG_WARN("fail to build isolation expr", K(ret));
|
||||
} else if (OB_FAIL(stmt->add_variable_node(isolation_var_node))) {
|
||||
} else if (OB_FAIL(stmt->add_variable_node(ObVariableSetStmt::make_variable_name_node(isolation_var_node)))) {
|
||||
LOG_WARN("fail to add variable node", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && set_access_mode) {
|
||||
if (OB_FAIL(build_access_expr(access_var_node.value_expr_, is_read_only))) {
|
||||
LOG_WARN("fail to build access expr", K(ret));
|
||||
} else if (OB_FAIL(stmt->add_variable_node(access_var_node))) {
|
||||
} else if (OB_FAIL(stmt->add_variable_node(ObVariableSetStmt::make_variable_name_node(access_var_node)))) {
|
||||
LOG_WARN("fail to add variable node", K(ret));
|
||||
} else {
|
||||
LOG_DEBUG("add variable node", K(is_read_only));
|
||||
|
@ -46,124 +46,27 @@ int ObVariableSetResolver::resolve(const ParseNode& parse_tree)
|
||||
variable_set_stmt->set_actual_tenant_id(session_info_->get_effective_tenant_id());
|
||||
ParseNode* set_node = NULL;
|
||||
ObVariableSetStmt::VariableSetNode var_node;
|
||||
ObVariableSetStmt::NamesSetNode names_node;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < parse_tree.num_child_; ++i) {
|
||||
if (OB_ISNULL(set_node = parse_tree.children_[i])) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("set node is NULL", K(ret));
|
||||
} else if (OB_UNLIKELY(T_VAR_VAL != set_node->type_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("set_node->type_ must be T_VAR_VAL", K(ret), K(set_node->type_));
|
||||
} else {
|
||||
ParseNode* var = NULL;
|
||||
switch (set_node->value_) {
|
||||
case 0:
|
||||
var_node.set_scope_ = ObSetVar::SET_SCOPE_SESSION;
|
||||
break;
|
||||
case 1:
|
||||
var_node.set_scope_ = ObSetVar::SET_SCOPE_GLOBAL;
|
||||
variable_set_stmt->set_has_global_variable(true);
|
||||
break;
|
||||
case 2:
|
||||
var_node.set_scope_ = ObSetVar::SET_SCOPE_SESSION;
|
||||
break;
|
||||
default:
|
||||
var_node.set_scope_ = ObSetVar::SET_SCOPE_NEXT_TRANS;
|
||||
break;
|
||||
} else if (T_VAR_VAL == set_node->type_) {
|
||||
if (OB_FAIL(resolve_set_variable(*set_node, var_node, variable_set_stmt))) {
|
||||
LOG_WARN("resolve set variable failed", K(ret));
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(var = set_node->children_[0])) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("var is NULL", K(ret));
|
||||
} else {
|
||||
ObString var_name;
|
||||
if (T_IDENT == var->type_) {
|
||||
var_node.is_system_variable_ = true;
|
||||
var_name.assign_ptr(var->str_value_, static_cast<int32_t>(var->str_len_));
|
||||
} else if (T_OBJ_ACCESS_REF == var->type_) { // Oracle mode
|
||||
const ParseNode* name_node = NULL;
|
||||
if (OB_ISNULL(name_node = var->children_[0]) || OB_UNLIKELY(var->children_[1] != NULL)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "Variable name not an identifier type");
|
||||
} else if (OB_UNLIKELY(name_node->type_ != T_IDENT)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "Variable name not an identifier type");
|
||||
} else {
|
||||
var_node.is_system_variable_ = true;
|
||||
var_name.assign_ptr(name_node->str_value_, static_cast<int32_t>(name_node->str_len_));
|
||||
}
|
||||
} else {
|
||||
var_node.is_system_variable_ = (T_SYSTEM_VARIABLE == var->type_);
|
||||
var_name.assign_ptr(var->str_value_, static_cast<int32_t>(var->str_len_));
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(ob_write_string(*allocator_, var_name, var_node.variable_name_))) {
|
||||
LOG_WARN("Can not malloc space for variable name", K(ret));
|
||||
} else {
|
||||
ObCharset::casedn(CS_TYPE_UTF8MB4_GENERAL_CI, var_node.variable_name_);
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(set_node->children_[1])) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("value node is NULL", K(ret));
|
||||
} else if (T_DEFAULT == set_node->children_[1]->type_) {
|
||||
// set system_variable = default
|
||||
var_node.is_set_default_ = true;
|
||||
} else if (var_node.is_system_variable_) {
|
||||
ParseNode value_node;
|
||||
if (T_IDENT == set_node->children_[1]->type_) {
|
||||
MEMCPY(&value_node, set_node->children_[1], sizeof(ParseNode));
|
||||
value_node.type_ = T_VARCHAR;
|
||||
} else if (T_COLUMN_REF == set_node->children_[1]->type_) {
|
||||
if (NULL == set_node->children_[1]->children_[0] && NULL == set_node->children_[1]->children_[1] &&
|
||||
NULL != set_node->children_[1]->children_[2]) {
|
||||
MEMCPY(&value_node, set_node->children_[1]->children_[2], sizeof(ParseNode));
|
||||
value_node.type_ = T_VARCHAR;
|
||||
} else {
|
||||
MEMCPY(&value_node, set_node->children_[1], sizeof(ParseNode));
|
||||
}
|
||||
} else if (T_OBJ_ACCESS_REF == set_node->children_[1]->type_) { // Oracle mode
|
||||
if (OB_ISNULL(set_node->children_[1]->children_[0]) ||
|
||||
OB_UNLIKELY(set_node->children_[1]->children_[1] != NULL)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "Variable value not a varchar nor identifier type");
|
||||
} else {
|
||||
MEMCPY(&value_node, set_node->children_[1]->children_[0], sizeof(ParseNode));
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
if (T_IDENT == set_node->children_[1]->children_[0]->type_) {
|
||||
value_node.type_ = T_VARCHAR;
|
||||
} else if (T_FUN_SYS == set_node->children_[1]->children_[0]->type_) {
|
||||
// do nothing
|
||||
} else {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "Variable value type");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
MEMCPY(&value_node, set_node->children_[1], sizeof(ParseNode));
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (0 == var_node.variable_name_.case_compare("ob_compatibility_mode") &&
|
||||
0 == strncasecmp(
|
||||
value_node.str_value_, "oracle", std::min(static_cast<int32_t>(value_node.str_len_), 6))) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "Not support oracle mode");
|
||||
} else if (OB_FAIL(
|
||||
ObResolverUtils::resolve_const_expr(params_, value_node, var_node.value_expr_, NULL))) {
|
||||
LOG_WARN("resolve variable value failed", K(ret));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (OB_FAIL(ObResolverUtils::resolve_const_expr(
|
||||
params_, *set_node->children_[1], var_node.value_expr_, NULL))) {
|
||||
LOG_WARN("resolve variable value failed", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && OB_FAIL(variable_set_stmt->add_variable_node(var_node))) {
|
||||
LOG_WARN("Add set entry failed", K(ret));
|
||||
}
|
||||
} else if (T_SET_NAMES == set_node->type_ || T_SET_CHARSET == set_node->type_) {
|
||||
if (OB_FAIL(resolve_set_names(*set_node, names_node)))
|
||||
LOG_WARN("resolve set names failed", K(ret));
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("unexpected set_node->type_ ", K(ret), K(set_node->type_));
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
const bool is_set_variable = T_VAR_VAL == set_node->type_;
|
||||
ObVariableSetStmt::VariableNamesSetNode var_names_node(is_set_variable, var_node, names_node);
|
||||
if (OB_FAIL(variable_set_stmt->add_variable_node(var_names_node))) {
|
||||
LOG_WARN("Add set entry failed", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -171,6 +74,183 @@ int ObVariableSetResolver::resolve(const ParseNode& parse_tree)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObVariableSetResolver::resolve_set_variable(const ParseNode &set_node,
|
||||
ObVariableSetStmt::VariableSetNode &var_node,
|
||||
ObVariableSetStmt* variable_set_stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ParseNode* var = NULL;
|
||||
switch (set_node.value_) {
|
||||
case 0:
|
||||
var_node.set_scope_ = ObSetVar::SET_SCOPE_SESSION;
|
||||
break;
|
||||
case 1:
|
||||
var_node.set_scope_ = ObSetVar::SET_SCOPE_GLOBAL;
|
||||
variable_set_stmt->set_has_global_variable(true);
|
||||
break;
|
||||
case 2:
|
||||
var_node.set_scope_ = ObSetVar::SET_SCOPE_SESSION;
|
||||
break;
|
||||
default:
|
||||
var_node.set_scope_ = ObSetVar::SET_SCOPE_NEXT_TRANS;
|
||||
break;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(var = set_node.children_[0])) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("var is NULL", K(ret));
|
||||
} else {
|
||||
ObString var_name;
|
||||
if (T_IDENT == var->type_) {
|
||||
var_node.is_system_variable_ = true;
|
||||
var_name.assign_ptr(var->str_value_, static_cast<int32_t>(var->str_len_));
|
||||
} else if (T_OBJ_ACCESS_REF == var->type_) { // Oracle mode
|
||||
const ParseNode* name_node = NULL;
|
||||
if (OB_ISNULL(name_node = var->children_[0]) || OB_UNLIKELY(var->children_[1] != NULL)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "Variable name not an identifier type");
|
||||
} else if (OB_UNLIKELY(name_node->type_ != T_IDENT)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "Variable name not an identifier type");
|
||||
} else {
|
||||
var_node.is_system_variable_ = true;
|
||||
var_name.assign_ptr(name_node->str_value_, static_cast<int32_t>(name_node->str_len_));
|
||||
}
|
||||
} else {
|
||||
var_node.is_system_variable_ = (T_SYSTEM_VARIABLE == var->type_);
|
||||
var_name.assign_ptr(var->str_value_, static_cast<int32_t>(var->str_len_));
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(ob_write_string(*allocator_, var_name, var_node.variable_name_))) {
|
||||
LOG_WARN("Can not malloc space for variable name", K(ret));
|
||||
} else {
|
||||
ObCharset::casedn(CS_TYPE_UTF8MB4_GENERAL_CI, var_node.variable_name_);
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(set_node.children_[1])) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("value node is NULL", K(ret));
|
||||
} else if (T_DEFAULT == set_node.children_[1]->type_) {
|
||||
// set system_variable = default
|
||||
var_node.is_set_default_ = true;
|
||||
} else if (var_node.is_system_variable_) {
|
||||
ParseNode value_node;
|
||||
if (T_IDENT == set_node.children_[1]->type_) {
|
||||
MEMCPY(&value_node, set_node.children_[1], sizeof(ParseNode));
|
||||
value_node.type_ = T_VARCHAR;
|
||||
} else if (T_COLUMN_REF == set_node.children_[1]->type_) {
|
||||
if (NULL == set_node.children_[1]->children_[0] && NULL == set_node.children_[1]->children_[1] &&
|
||||
NULL != set_node.children_[1]->children_[2]) {
|
||||
MEMCPY(&value_node, set_node.children_[1]->children_[2], sizeof(ParseNode));
|
||||
value_node.type_ = T_VARCHAR;
|
||||
} else {
|
||||
MEMCPY(&value_node, set_node.children_[1], sizeof(ParseNode));
|
||||
}
|
||||
} else if (T_OBJ_ACCESS_REF == set_node.children_[1]->type_) { // Oracle mode
|
||||
if (OB_ISNULL(set_node.children_[1]->children_[0]) ||
|
||||
OB_UNLIKELY(set_node.children_[1]->children_[1] != NULL)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "Variable value not a varchar nor identifier type");
|
||||
} else {
|
||||
MEMCPY(&value_node, set_node.children_[1]->children_[0], sizeof(ParseNode));
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
if (T_IDENT == set_node.children_[1]->children_[0]->type_) {
|
||||
value_node.type_ = T_VARCHAR;
|
||||
} else if (T_FUN_SYS == set_node.children_[1]->children_[0]->type_) {
|
||||
// do nothing
|
||||
} else {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "Variable value type");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
MEMCPY(&value_node, set_node.children_[1], sizeof(ParseNode));
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (0 == var_node.variable_name_.case_compare("ob_compatibility_mode") &&
|
||||
0 == strncasecmp(
|
||||
value_node.str_value_, "oracle", std::min(static_cast<int32_t>(value_node.str_len_), 6))) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "Not support oracle mode");
|
||||
} else if (OB_FAIL(
|
||||
ObResolverUtils::resolve_const_expr(params_, value_node, var_node.value_expr_, NULL))) {
|
||||
LOG_WARN("resolve variable value failed", K(ret));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (OB_FAIL(ObResolverUtils::resolve_const_expr(
|
||||
params_, *set_node.children_[1], var_node.value_expr_, NULL))) {
|
||||
LOG_WARN("resolve variable value failed", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObVariableSetResolver::resolve_set_names(const ParseNode &set_node,
|
||||
ObVariableSetStmt::NamesSetNode &names_node)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(set_node.children_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_RESV_LOG(WARN, "set_node.children_ is null.", K(ret));
|
||||
} else if (OB_ISNULL(set_node.children_[0])) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_RESV_LOG(WARN, "set_node.children_[0] is null.", K(ret));
|
||||
} else {
|
||||
if (T_SET_NAMES == set_node.type_) {
|
||||
// SET NAMES
|
||||
names_node.is_set_names_ = true;
|
||||
if (T_DEFAULT == set_node.children_[0]->type_) {
|
||||
names_node.is_default_charset_ = true;
|
||||
} else {
|
||||
names_node.is_default_charset_ = false;
|
||||
ObString charset;
|
||||
charset.assign_ptr(
|
||||
set_node.children_[0]->str_value_, static_cast<int32_t>(set_node.children_[0]->str_len_));
|
||||
if (0 == charset.case_compare("utf16")) {
|
||||
ret = OB_ERR_WRONG_VALUE_FOR_VAR;
|
||||
LOG_USER_ERROR(OB_ERR_WRONG_VALUE_FOR_VAR,
|
||||
static_cast<int>(strlen("character_set_client")),
|
||||
"character_set_client",
|
||||
charset.length(),
|
||||
charset.ptr());
|
||||
} else {
|
||||
names_node.charset_ = charset;
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (NULL == set_node.children_[1]) {
|
||||
names_node.is_default_collation_ = true;
|
||||
} else {
|
||||
names_node.is_default_collation_ = false;
|
||||
ObString collation;
|
||||
collation.assign_ptr(
|
||||
set_node.children_[1]->str_value_, static_cast<int32_t>(set_node.children_[1]->str_len_));
|
||||
names_node.collation_ = collation;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// SET CHARACTER SET
|
||||
names_node.is_set_names_ = false;
|
||||
if (T_DEFAULT == set_node.children_[0]->type_) {
|
||||
names_node.is_default_charset_ = true;
|
||||
} else {
|
||||
names_node.is_default_charset_ = false;
|
||||
names_node.charset_.assign_ptr(set_node.children_[0]->str_value_,
|
||||
static_cast<int32_t>(set_node.children_[0]->str_len_));
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG_DEBUG("resolve set names", K(names_node));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ObAlterSessionSetResolver::ObAlterSessionSetResolver(ObResolverParams& params) : ObStmtResolver(params)
|
||||
{}
|
||||
|
||||
@ -252,7 +332,8 @@ int ObAlterSessionSetResolver::resolve(const ParseNode& parse_tree)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && OB_FAIL(variable_set_stmt->add_variable_node(var_node))) {
|
||||
if (OB_SUCC(ret) && OB_FAIL(variable_set_stmt->add_variable_node(
|
||||
ObVariableSetStmt::make_variable_name_node(var_node)))) {
|
||||
LOG_WARN("Add set entry failed", K(ret));
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,9 @@ public:
|
||||
virtual ~ObVariableSetResolver();
|
||||
|
||||
virtual int resolve(const ParseNode& parse_tree);
|
||||
int resolve_set_variable(const ParseNode &set_node, ObVariableSetStmt::VariableSetNode &var_node,
|
||||
ObVariableSetStmt* variable_set_stmt);
|
||||
int resolve_set_names(const ParseNode &set_node, ObVariableSetStmt::NamesSetNode &names_node);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObVariableSetResolver);
|
||||
|
@ -16,7 +16,7 @@
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
namespace sql {
|
||||
int ObVariableSetStmt::get_variable_node(int64_t index, ObVariableSetStmt::VariableSetNode& var_node) const
|
||||
int ObVariableSetStmt::get_variable_node(int64_t index, ObVariableSetStmt::VariableNamesSetNode& var_node) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(index < 0 || index >= variable_nodes_.count())) {
|
||||
|
@ -41,6 +41,47 @@ public:
|
||||
ObRawExpr* value_expr_;
|
||||
bool is_set_default_;
|
||||
};
|
||||
class NamesSetNode {
|
||||
public:
|
||||
NamesSetNode()
|
||||
: is_set_names_(true),
|
||||
is_default_charset_(true),
|
||||
is_default_collation_(true),
|
||||
charset_(),
|
||||
collation_()
|
||||
{}
|
||||
virtual ~NamesSetNode()
|
||||
{}
|
||||
TO_STRING_KV(K_(is_set_names), K_(is_default_charset), K_(is_default_collation), K_(charset), K_(collation));
|
||||
|
||||
bool is_set_names_; // SET NAMES or SET CHARSET?
|
||||
bool is_default_charset_;
|
||||
bool is_default_collation_;
|
||||
common::ObString charset_;
|
||||
common::ObString collation_;
|
||||
};
|
||||
|
||||
class VariableNamesSetNode {
|
||||
public:
|
||||
VariableNamesSetNode()
|
||||
: is_set_variable_(true),
|
||||
var_set_node_(),
|
||||
names_set_node_()
|
||||
{}
|
||||
VariableNamesSetNode(bool is_set_variable, const VariableSetNode &var_node,
|
||||
const NamesSetNode &names_node)
|
||||
: is_set_variable_(is_set_variable),
|
||||
var_set_node_(var_node),
|
||||
names_set_node_(names_node)
|
||||
{}
|
||||
virtual ~VariableNamesSetNode()
|
||||
{}
|
||||
TO_STRING_KV(K_(is_set_variable), K_(var_set_node), K_(names_set_node));
|
||||
|
||||
bool is_set_variable_; // set variables or set names
|
||||
VariableSetNode var_set_node_;
|
||||
NamesSetNode names_set_node_;
|
||||
};
|
||||
|
||||
ObVariableSetStmt()
|
||||
: ObDDLStmt(stmt::T_VARIABLE_SET),
|
||||
@ -51,6 +92,12 @@ public:
|
||||
virtual ~ObVariableSetStmt()
|
||||
{}
|
||||
|
||||
static inline VariableNamesSetNode make_variable_name_node(VariableSetNode& var_set_node) {
|
||||
return VariableNamesSetNode(true, var_set_node, NamesSetNode());
|
||||
}
|
||||
static inline VariableNamesSetNode make_variable_name_node(NamesSetNode& names_set_node) {
|
||||
return VariableNamesSetNode(false, VariableSetNode(), names_set_node);
|
||||
}
|
||||
inline void set_actual_tenant_id(uint64_t actual_tenant_id)
|
||||
{
|
||||
actual_tenant_id_ = actual_tenant_id;
|
||||
@ -59,9 +106,9 @@ public:
|
||||
{
|
||||
return actual_tenant_id_;
|
||||
}
|
||||
inline int add_variable_node(const VariableSetNode& node);
|
||||
inline int add_variable_node(const VariableNamesSetNode& node);
|
||||
inline int64_t get_variables_size() const;
|
||||
int get_variable_node(int64_t index, VariableSetNode& node) const;
|
||||
int get_variable_node(int64_t index, VariableNamesSetNode& node) const;
|
||||
inline void set_has_global_variable(bool has_global_variable)
|
||||
{
|
||||
has_global_variable_ = has_global_variable;
|
||||
@ -86,7 +133,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
const common::ObIArray<VariableSetNode>& get_variable_nodes() const
|
||||
const common::ObIArray<VariableNamesSetNode>& get_variable_nodes() const
|
||||
{
|
||||
return variable_nodes_;
|
||||
}
|
||||
@ -98,13 +145,13 @@ public:
|
||||
|
||||
private:
|
||||
uint64_t actual_tenant_id_;
|
||||
common::ObArray<VariableSetNode, common::ModulePageAllocator, true> variable_nodes_;
|
||||
common::ObArray<VariableNamesSetNode, common::ModulePageAllocator, true> variable_nodes_;
|
||||
bool has_global_variable_;
|
||||
obrpc::ObModifySysVarArg modify_sysvar_arg_;
|
||||
DISALLOW_COPY_AND_ASSIGN(ObVariableSetStmt);
|
||||
};
|
||||
|
||||
inline int ObVariableSetStmt::add_variable_node(const VariableSetNode& node)
|
||||
inline int ObVariableSetStmt::add_variable_node(const VariableNamesSetNode& node)
|
||||
{
|
||||
return variable_nodes_.push_back(node);
|
||||
}
|
||||
|
@ -129,20 +129,26 @@ int ObCreateTenantResolver::resolve(const ParseNode& parse_tree)
|
||||
|
||||
bool is_oracle_mode = false;
|
||||
if (OB_SUCC(ret)) {
|
||||
for (int64_t i = 0; i < mystmt->get_sys_var_nodes().count(); i++) {
|
||||
const ObVariableSetStmt::VariableSetNode& node = mystmt->get_sys_var_nodes().at(i);
|
||||
if (0 == node.variable_name_.case_compare("ob_compatibility_mode")) {
|
||||
ObConstRawExpr* const_expr = static_cast<ObConstRawExpr*>(node.value_expr_);
|
||||
if (nullptr == const_expr) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("const expr is null", K(ret));
|
||||
} else {
|
||||
ObObj value = const_expr->get_value();
|
||||
ObString str;
|
||||
if (OB_FAIL(value.get_string(str))) {
|
||||
LOG_WARN("get string failed", K(ret));
|
||||
} else if (0 == str.case_compare("oracle")) {
|
||||
is_oracle_mode = true;
|
||||
for (int64_t i = 0; i < mystmt->get_sys_var_nodes().count() && OB_SUCC(ret); i++) {
|
||||
const ObVariableSetStmt::VariableNamesSetNode& var_names_node = mystmt->get_sys_var_nodes().at(i);
|
||||
if (OB_UNLIKELY(!var_names_node.is_set_variable_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("not allow to set names when create tenant according to symtax", K(ret));
|
||||
} else {
|
||||
const ObVariableSetStmt::VariableSetNode& node = var_names_node.var_set_node_;
|
||||
if (0 == node.variable_name_.case_compare("ob_compatibility_mode")) {
|
||||
ObConstRawExpr* const_expr = static_cast<ObConstRawExpr*>(node.value_expr_);
|
||||
if (nullptr == const_expr) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("const expr is null", K(ret));
|
||||
} else {
|
||||
ObObj value = const_expr->get_value();
|
||||
ObString str;
|
||||
if (OB_FAIL(value.get_string(str))) {
|
||||
LOG_WARN("get string failed", K(ret));
|
||||
} else if (0 == str.case_compare("oracle")) {
|
||||
is_oracle_mode = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,15 +59,15 @@ public:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
int add_sys_var_node(const ObVariableSetStmt::VariableSetNode& node)
|
||||
int add_sys_var_node(const ObVariableSetStmt::VariableNamesSetNode& node)
|
||||
{
|
||||
return sys_var_nodes_.push_back(node);
|
||||
}
|
||||
const common::ObIArray<ObVariableSetStmt::VariableSetNode>& get_sys_var_nodes() const
|
||||
const common::ObIArray<ObVariableSetStmt::VariableNamesSetNode>& get_sys_var_nodes() const
|
||||
{
|
||||
return sys_var_nodes_;
|
||||
}
|
||||
int assign_variable_nodes(const common::ObIArray<ObVariableSetStmt::VariableSetNode>& other);
|
||||
int assign_variable_nodes(const common::ObIArray<ObVariableSetStmt::VariableNamesSetNode>& other);
|
||||
int set_default_tablegroup_name(const common::ObString& tablegroup_name);
|
||||
virtual obrpc::ObDDLArg& get_ddl_arg()
|
||||
{
|
||||
@ -76,7 +76,7 @@ public:
|
||||
|
||||
private:
|
||||
obrpc::ObCreateTenantArg create_tenant_arg_;
|
||||
common::ObArray<ObVariableSetStmt::VariableSetNode, common::ModulePageAllocator, true> sys_var_nodes_;
|
||||
common::ObArray<ObVariableSetStmt::VariableNamesSetNode, common::ModulePageAllocator, true> sys_var_nodes_;
|
||||
DISALLOW_COPY_AND_ASSIGN(ObCreateTenantStmt);
|
||||
};
|
||||
|
||||
@ -85,7 +85,7 @@ inline obrpc::ObCreateTenantArg& ObCreateTenantStmt::get_create_tenant_arg()
|
||||
return create_tenant_arg_;
|
||||
}
|
||||
|
||||
inline int ObCreateTenantStmt::assign_variable_nodes(const common::ObIArray<ObVariableSetStmt::VariableSetNode>& other)
|
||||
inline int ObCreateTenantStmt::assign_variable_nodes(const common::ObIArray<ObVariableSetStmt::VariableNamesSetNode>& other)
|
||||
{
|
||||
return sys_var_nodes_.assign(other);
|
||||
}
|
||||
|
@ -99,15 +99,15 @@ public:
|
||||
{
|
||||
return modify_tenant_arg_.check_normal_tenant_can_do(normal_can_do);
|
||||
}
|
||||
int add_sys_var_node(const ObVariableSetStmt::VariableSetNode& node)
|
||||
int add_sys_var_node(const ObVariableSetStmt::VariableNamesSetNode& node)
|
||||
{
|
||||
return sys_var_nodes_.push_back(node);
|
||||
}
|
||||
const common::ObIArray<ObVariableSetStmt::VariableSetNode>& get_sys_var_nodes() const
|
||||
const common::ObIArray<ObVariableSetStmt::VariableNamesSetNode>& get_sys_var_nodes() const
|
||||
{
|
||||
return sys_var_nodes_;
|
||||
}
|
||||
int assign_variable_nodes(const common::ObIArray<ObVariableSetStmt::VariableSetNode>& other);
|
||||
int assign_variable_nodes(const common::ObIArray<ObVariableSetStmt::VariableNamesSetNode>& other);
|
||||
int set_default_tablegroup_name(const common::ObString& tablegroup_name);
|
||||
|
||||
virtual obrpc::ObDDLArg& get_ddl_arg()
|
||||
@ -119,7 +119,7 @@ public:
|
||||
private:
|
||||
bool for_current_tenant_;
|
||||
obrpc::ObModifyTenantArg modify_tenant_arg_;
|
||||
common::ObArray<ObVariableSetStmt::VariableSetNode, common::ModulePageAllocator, true> sys_var_nodes_;
|
||||
common::ObArray<ObVariableSetStmt::VariableNamesSetNode, common::ModulePageAllocator, true> sys_var_nodes_;
|
||||
ObModifyTenantSpecialOption special_option_;
|
||||
DISALLOW_COPY_AND_ASSIGN(ObModifyTenantStmt);
|
||||
};
|
||||
@ -145,7 +145,7 @@ inline const common::ObString& ObModifyTenantStmt::get_new_tenant_name() const
|
||||
return modify_tenant_arg_.new_tenant_name_;
|
||||
}
|
||||
|
||||
inline int ObModifyTenantStmt::assign_variable_nodes(const common::ObIArray<ObVariableSetStmt::VariableSetNode>& other)
|
||||
inline int ObModifyTenantStmt::assign_variable_nodes(const common::ObIArray<ObVariableSetStmt::VariableNamesSetNode>& other)
|
||||
{
|
||||
return sys_var_nodes_.assign(other);
|
||||
}
|
||||
|
@ -81,7 +81,6 @@
|
||||
#include "sql/resolver/cmd/ob_show_resolver.h"
|
||||
#include "sql/resolver/cmd/ob_alter_system_resolver.h"
|
||||
#include "sql/resolver/cmd/ob_kill_resolver.h"
|
||||
#include "sql/resolver/cmd/ob_set_names_resolver.h"
|
||||
#include "sql/resolver/cmd/ob_set_transaction_resolver.h"
|
||||
#include "sql/resolver/cmd/ob_bootstrap_resolver.h"
|
||||
#include "sql/resolver/cmd/ob_empty_query_resolver.h"
|
||||
@ -643,12 +642,6 @@ int ObResolver::resolve(IsPrepared if_prepared, const ParseNode& parse_tree, ObS
|
||||
REGISTER_STMT_RESOLVER(AlterSessionSet);
|
||||
break;
|
||||
}
|
||||
case T_SET_NAMES:
|
||||
// fall through
|
||||
case T_SET_CHARSET: {
|
||||
REGISTER_STMT_RESOLVER(SetNames);
|
||||
break;
|
||||
}
|
||||
case T_KILL: {
|
||||
REGISTER_STMT_RESOLVER(Kill);
|
||||
break;
|
||||
|
@ -594,6 +594,9 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <>
|
||||
int create_stmt<ObSelectStmt>(ObSelectStmt*& stmt);
|
||||
|
||||
inline int free_stmt(ObSelectStmt* stmt)
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
|
@ -123,7 +123,6 @@ OB_STMT_TYPE_DEF(T_ALTER_TABLEGROUP, get_alter_tablegroup_stmt_need_privs, 109)
|
||||
OB_STMT_TYPE_DEF(T_TRUNCATE_TABLE, get_truncate_table_stmt_need_privs, 110)
|
||||
OB_STMT_TYPE_DEF(T_RENAME_TABLE, get_rename_table_stmt_need_privs, 111)
|
||||
OB_STMT_TYPE_DEF(T_CREATE_TABLE_LIKE, get_create_table_like_stmt_need_privs, 112)
|
||||
OB_STMT_TYPE_DEF(T_SET_NAMES, no_priv_needed, 113)
|
||||
OB_STMT_TYPE_DEF(T_CLEAR_LOCATION_CACHE, get_sys_tenant_alter_system_priv, 114)
|
||||
OB_STMT_TYPE_DEF(T_RELOAD_GTS, get_sys_tenant_alter_system_priv, 115)
|
||||
OB_STMT_TYPE_DEF(T_RELOAD_UNIT, get_sys_tenant_alter_system_priv, 116)
|
||||
|
@ -2620,58 +2620,65 @@ set names latin1;
|
||||
question_mask_size: 0
|
||||
|
||||
|--[0],[T_STMT_LIST], str_value_=[], value=[9223372036854775807]
|
||||
|--[0],[T_SET_NAMES], str_value_=[], value=[0]
|
||||
|--[0],[T_VARCHAR], str_value_=[latin1], value=[9223372036854775807]
|
||||
|--[0],[T_VARIABLE_SET], str_value_=[], value=[0]
|
||||
|--[0],[T_SET_NAMES], str_value_=[], value=[9223372036854775807]
|
||||
|--[0],[T_VARCHAR], str_value_=[latin1], value=[9223372036854775807]
|
||||
|
||||
************** Case 126 ***************
|
||||
set names 'latin1';
|
||||
question_mask_size: 0
|
||||
|
||||
|--[0],[T_STMT_LIST], str_value_=[], value=[9223372036854775807]
|
||||
|--[0],[T_SET_NAMES], str_value_=[], value=[0]
|
||||
|--[0],[T_VARCHAR], str_value_=[latin1], value=[9223372036854775807]
|
||||
|--[0],[T_VARIABLE_SET], str_value_=[], value=[0]
|
||||
|--[0],[T_SET_NAMES], str_value_=[], value=[9223372036854775807]
|
||||
|--[0],[T_VARCHAR], str_value_=[latin1], value=[9223372036854775807]
|
||||
|
||||
************** Case 127 ***************
|
||||
set names utf8 collate 'utf8_general_ci';
|
||||
question_mask_size: 0
|
||||
|
||||
|--[0],[T_STMT_LIST], str_value_=[], value=[9223372036854775807]
|
||||
|--[0],[T_SET_NAMES], str_value_=[], value=[0]
|
||||
|--[0],[T_VARCHAR], str_value_=[utf8], value=[9223372036854775807]
|
||||
|--[1],[T_COLLATION], str_value_=[utf8_general_ci], value=[9223372036854775807]
|
||||
|--[0],[T_VARIABLE_SET], str_value_=[], value=[0]
|
||||
|--[0],[T_SET_NAMES], str_value_=[], value=[9223372036854775807]
|
||||
|--[0],[T_VARCHAR], str_value_=[utf8], value=[9223372036854775807]
|
||||
|--[1],[T_COLLATION], str_value_=[utf8_general_ci], value=[9223372036854775807]
|
||||
|
||||
************** Case 128 ***************
|
||||
set names utf8 collate utf8_general_ci;
|
||||
question_mask_size: 0
|
||||
|
||||
|--[0],[T_STMT_LIST], str_value_=[], value=[9223372036854775807]
|
||||
|--[0],[T_SET_NAMES], str_value_=[], value=[0]
|
||||
|--[0],[T_VARCHAR], str_value_=[utf8], value=[9223372036854775807]
|
||||
|--[1],[T_COLLATION], str_value_=[utf8_general_ci], value=[9223372036854775807]
|
||||
|--[0],[T_VARIABLE_SET], str_value_=[], value=[0]
|
||||
|--[0],[T_SET_NAMES], str_value_=[], value=[9223372036854775807]
|
||||
|--[0],[T_VARCHAR], str_value_=[utf8], value=[9223372036854775807]
|
||||
|--[1],[T_COLLATION], str_value_=[utf8_general_ci], value=[9223372036854775807]
|
||||
|
||||
************** Case 129 ***************
|
||||
set character set utf8;
|
||||
question_mask_size: 0
|
||||
|
||||
|--[0],[T_STMT_LIST], str_value_=[], value=[9223372036854775807]
|
||||
|--[0],[T_SET_CHARSET], str_value_=[], value=[0]
|
||||
|--[0],[T_VARCHAR], str_value_=[utf8], value=[9223372036854775807]
|
||||
|--[0],[T_VARIABLE_SET], str_value_=[], value=[0]
|
||||
|--[0],[T_SET_CHARSET], str_value_=[], value=[9223372036854775807]
|
||||
|--[0],[T_VARCHAR], str_value_=[utf8], value=[9223372036854775807]
|
||||
|
||||
************** Case 130 ***************
|
||||
set character set 'utf8';
|
||||
question_mask_size: 0
|
||||
|
||||
|--[0],[T_STMT_LIST], str_value_=[], value=[9223372036854775807]
|
||||
|--[0],[T_SET_CHARSET], str_value_=[], value=[0]
|
||||
|--[0],[T_VARCHAR], str_value_=[utf8], value=[9223372036854775807]
|
||||
|--[0],[T_VARIABLE_SET], str_value_=[], value=[0]
|
||||
|--[0],[T_SET_CHARSET], str_value_=[], value=[9223372036854775807]
|
||||
|--[0],[T_VARCHAR], str_value_=[utf8], value=[9223372036854775807]
|
||||
|
||||
************** Case 131 ***************
|
||||
set charset utf8;
|
||||
question_mask_size: 0
|
||||
|
||||
|--[0],[T_STMT_LIST], str_value_=[], value=[9223372036854775807]
|
||||
|--[0],[T_SET_CHARSET], str_value_=[], value=[0]
|
||||
|--[0],[T_VARCHAR], str_value_=[utf8], value=[9223372036854775807]
|
||||
|--[0],[T_VARIABLE_SET], str_value_=[], value=[0]
|
||||
|--[0],[T_SET_CHARSET], str_value_=[], value=[9223372036854775807]
|
||||
|--[0],[T_VARCHAR], str_value_=[utf8], value=[9223372036854775807]
|
||||
|
||||
************** Case 132 ***************
|
||||
select _utf8 'abc', _utf8mb4 'def' collate utf8mb4_general_ci from t1 where c1 collate utf8_bin = 'xyz' collate utf8_bin;
|
||||
|
@ -17496,18 +17496,26 @@ question_mask_size: 0
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_SET_NAMES",
|
||||
"type":"T_VARIABLE_SET",
|
||||
"int_val":0,
|
||||
"str_len":0,
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_VARCHAR",
|
||||
"type":"T_SET_NAMES",
|
||||
"int_val":9223372036854775807,
|
||||
"str_len":6,
|
||||
"str_val":"latin1"
|
||||
},
|
||||
{ }
|
||||
"str_len":0,
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_VARCHAR",
|
||||
"int_val":9223372036854775807,
|
||||
"str_len":6,
|
||||
"str_val":"latin1"
|
||||
},
|
||||
{ }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@ -17522,18 +17530,26 @@ question_mask_size: 0
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_SET_NAMES",
|
||||
"type":"T_VARIABLE_SET",
|
||||
"int_val":0,
|
||||
"str_len":0,
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_VARCHAR",
|
||||
"type":"T_SET_NAMES",
|
||||
"int_val":9223372036854775807,
|
||||
"str_len":6,
|
||||
"str_val":"latin1"
|
||||
},
|
||||
{ }
|
||||
"str_len":0,
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_VARCHAR",
|
||||
"int_val":9223372036854775807,
|
||||
"str_len":6,
|
||||
"str_val":"latin1"
|
||||
},
|
||||
{ }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@ -17548,22 +17564,30 @@ question_mask_size: 0
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_SET_NAMES",
|
||||
"type":"T_VARIABLE_SET",
|
||||
"int_val":0,
|
||||
"str_len":0,
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_VARCHAR",
|
||||
"type":"T_SET_NAMES",
|
||||
"int_val":9223372036854775807,
|
||||
"str_len":4,
|
||||
"str_val":"utf8"
|
||||
},
|
||||
{
|
||||
"type":"T_COLLATION",
|
||||
"int_val":9223372036854775807,
|
||||
"str_len":15,
|
||||
"str_val":"utf8_general_ci"
|
||||
"str_len":0,
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_VARCHAR",
|
||||
"int_val":9223372036854775807,
|
||||
"str_len":4,
|
||||
"str_val":"utf8"
|
||||
},
|
||||
{
|
||||
"type":"T_COLLATION",
|
||||
"int_val":9223372036854775807,
|
||||
"str_len":15,
|
||||
"str_val":"utf8_general_ci"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -17579,22 +17603,30 @@ question_mask_size: 0
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_SET_NAMES",
|
||||
"type":"T_VARIABLE_SET",
|
||||
"int_val":0,
|
||||
"str_len":0,
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_VARCHAR",
|
||||
"type":"T_SET_NAMES",
|
||||
"int_val":9223372036854775807,
|
||||
"str_len":4,
|
||||
"str_val":"utf8"
|
||||
},
|
||||
{
|
||||
"type":"T_COLLATION",
|
||||
"int_val":9223372036854775807,
|
||||
"str_len":15,
|
||||
"str_val":"utf8_general_ci"
|
||||
"str_len":0,
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_VARCHAR",
|
||||
"int_val":9223372036854775807,
|
||||
"str_len":4,
|
||||
"str_val":"utf8"
|
||||
},
|
||||
{
|
||||
"type":"T_COLLATION",
|
||||
"int_val":9223372036854775807,
|
||||
"str_len":15,
|
||||
"str_val":"utf8_general_ci"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -17610,16 +17642,24 @@ question_mask_size: 0
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_SET_CHARSET",
|
||||
"type":"T_VARIABLE_SET",
|
||||
"int_val":0,
|
||||
"str_len":0,
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_VARCHAR",
|
||||
"type":"T_SET_CHARSET",
|
||||
"int_val":9223372036854775807,
|
||||
"str_len":4,
|
||||
"str_val":"utf8"
|
||||
"str_len":0,
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_VARCHAR",
|
||||
"int_val":9223372036854775807,
|
||||
"str_len":4,
|
||||
"str_val":"utf8"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -17635,16 +17675,24 @@ question_mask_size: 0
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_SET_CHARSET",
|
||||
"type":"T_VARIABLE_SET",
|
||||
"int_val":0,
|
||||
"str_len":0,
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_VARCHAR",
|
||||
"type":"T_SET_CHARSET",
|
||||
"int_val":9223372036854775807,
|
||||
"str_len":4,
|
||||
"str_val":"utf8"
|
||||
"str_len":0,
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_VARCHAR",
|
||||
"int_val":9223372036854775807,
|
||||
"str_len":4,
|
||||
"str_val":"utf8"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -17660,16 +17708,24 @@ question_mask_size: 0
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_SET_CHARSET",
|
||||
"type":"T_VARIABLE_SET",
|
||||
"int_val":0,
|
||||
"str_len":0,
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_VARCHAR",
|
||||
"type":"T_SET_CHARSET",
|
||||
"int_val":9223372036854775807,
|
||||
"str_len":4,
|
||||
"str_val":"utf8"
|
||||
"str_len":0,
|
||||
"str_val":"",
|
||||
"children": [
|
||||
{
|
||||
"type":"T_VARCHAR",
|
||||
"int_val":9223372036854775807,
|
||||
"str_len":4,
|
||||
"str_val":"utf8"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user