提交 878c594b 编写于 作者: S st0 提交者: LINGuanRen

support set names/charset and variables in one sql

上级 fa9b5fdf
......@@ -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
......
/**
* 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;
}
/**
* 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("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("node.value_expr_ is NULL", K(ret));
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*/
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 {
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*/
// 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;
// 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());
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));
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));
}
}
}
}
......
......@@ -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
......
......@@ -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));
}
}
......
/**
* 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
/**
* 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
/**
* 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,131 +46,211 @@ 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_)) {
} 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));
}
} 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("set_node->type_ must be T_VAR_VAL", K(ret), K(set_node->type_));
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));
}
}
}
}
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 {
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;
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));
}
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 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 {
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));
}
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));
}
}
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 {
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));
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",
"int_val":9223372036854775807,
"str_len":4,
"str_val":"utf8"
},
{
"type":"T_COLLATION",
"type":"T_SET_NAMES",
"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",
"int_val":9223372036854775807,
"str_len":4,
"str_val":"utf8"
},
{
"type":"T_COLLATION",
"type":"T_SET_NAMES",
"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"
}
]
}
]
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册