[FEAT MERGE]4_1_sql_feature

Co-authored-by: leslieyuchen <leslieyuchen@gmail.com>
Co-authored-by: Charles0429 <xiezhenjiang@gmail.com>
Co-authored-by: raywill <hustos@gmail.com>
This commit is contained in:
obdev
2023-01-28 16:01:26 +08:00
committed by ob-robot
parent 3080f2b66f
commit 2d19a9d8f5
846 changed files with 161957 additions and 116661 deletions

View File

@ -77,8 +77,13 @@
#include "sql/udr/ob_udr_mgr.h"
#include "sql/udr/ob_udr_analyzer.h"
#include "common/ob_smart_call.h"
#include "sql/ob_optimizer_trace_impl.h"
#include "share/resource_manager/ob_resource_manager.h"
#include "share/resource_manager/ob_cgroup_ctrl.h"
#include "sql/ob_optimizer_trace_impl.h"
#include "sql/monitor/ob_sql_plan_manager.h"
#include "sql/monitor/ob_sql_plan.h"
#include "sql/optimizer/ob_explain_log_plan.h"
namespace oceanbase
{
@ -1443,8 +1448,9 @@ int ObSql::handle_pl_execute(const ObString &sql,
}
if (session.get_in_transaction()) {
if (ObStmt::is_dml_write_stmt(result.get_stmt_type())) {
if (OB_SUCC(ret) && session.get_in_transaction()) {
if (ObStmt::is_dml_write_stmt(result.get_stmt_type()) ||
ObStmt::is_savepoint_stmt(result.get_stmt_type())) {
session.set_has_inner_dml_write(true);
}
}
@ -2060,6 +2066,8 @@ int ObSql::handle_remote_query(const ObRemoteSqlInfo &remote_sql_info,
int ret = OB_SUCCESS;
//trim the sql first, let 'select c1 from t' and ' select c1 from t' and hit the same plan_cache
const ObString &trimed_stmt = remote_sql_info.remote_sql_;
FLTSpanGuard(remote_compile);
FLT_SET_TAG(sql_text, trimed_stmt);
ObIAllocator &allocator = THIS_WORKER.get_sql_arena_allocator();
ObSQLSessionInfo *session = exec_ctx.get_my_session();
@ -2580,6 +2588,7 @@ int ObSql::generate_stmt(ParseResult &parse_result,
context.all_equal_param_constraints_ = &(resolver_ctx.query_ctx_->all_equal_param_constraints_);
context.all_pre_calc_constraints_ = &(resolver_ctx.query_ctx_->all_pre_calc_constraints_);
context.all_expr_constraints_ = &(resolver_ctx.query_ctx_->all_expr_constraints_);
context.all_priv_constraints_ = &(resolver_ctx.query_ctx_->all_priv_constraints_);
context.cur_stmt_ = stmt;
context.res_map_rule_id_ = resolver_ctx.query_ctx_->res_map_rule_id_;
context.res_map_rule_param_idx_ = resolver_ctx.query_ctx_->res_map_rule_param_idx_;
@ -2714,10 +2723,8 @@ int ObSql::generate_physical_plan(ParseResult &parse_result,
ObIAllocator &allocator = result.get_mem_pool();
ObStmtNeedPrivs stmt_need_privs;
ObStmtOraNeedPrivs stmt_ora_need_privs;
const uint64_t tenant_id = result.get_session().get_effective_tenant_id();
stmt_need_privs.need_privs_.set_allocator(&allocator);
stmt_ora_need_privs.need_privs_.set_allocator(&allocator);
uint64_t aggregate_setting = 0;
// TODO: @linlin.xll remove ori_bl_key after eval_udf use identical sql ctx.
ObPlanBaseKeyGuard guard(sql_ctx.spm_ctx_.bl_key_);
_LOG_DEBUG("start to generate physical plan for query.(query = %.*s)",
@ -2745,7 +2752,8 @@ int ObSql::generate_physical_plan(ParseResult &parse_result,
} else if (OB_FAIL(ObPrivilegeCheck::check_password_expired(sql_ctx,
basic_stmt->get_stmt_type()))) {
LOG_WARN("Falied to check password expired", K(ret));
} else if (sql_ctx.multi_stmt_item_.is_batched_multi_stmt() && NULL != pc_ctx &&
} else if (sql_ctx.multi_stmt_item_.is_batched_multi_stmt() &&
NULL != pc_ctx &&
OB_FAIL(check_batched_multi_stmt_after_resolver(*pc_ctx,
*basic_stmt,
is_valid))) {
@ -2753,184 +2761,34 @@ int ObSql::generate_physical_plan(ParseResult &parse_result,
} else if (!is_valid) {
ret = OB_BATCHED_MULTI_STMT_ROLLBACK;
LOG_WARN("batched multi_stmt needs rollback", K(ret));
} else { /*do nothing*/ }
if (OB_SUCC(ret)) {
if (basic_stmt->is_dml_stmt()
|| basic_stmt->is_explain_stmt()
|| basic_stmt->is_help_stmt()) {
ObPhysicalPlanCtx *pctx = result.get_exec_context().get_physical_plan_ctx();
bool allow_audit = false;
ObArray<ObAuditUnit> audit_units;
if (OB_ISNULL(pctx) || OB_ISNULL(result.get_exec_context().get_expr_factory())) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("Physical plan ctx should not be NULL", K(ret));
} else if (OB_ISNULL(result.get_exec_context().get_stmt_factory()->get_query_ctx())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("query ctx is null", K(ret));
} else if (OB_FAIL(fill_result_set(result, &sql_ctx, mode, *basic_stmt))) {
LOG_WARN("Failed to fill result set", K(ret));
} else if (OB_FAIL(sql_ctx.session_info_->get_sys_variable(share::SYS_VAR__AGGREGATION_OPTIMIZATION_SETTINGS,
aggregate_setting))) {
LOG_WARN("failed to get aggregate setting", K(ret));
} else {
ObDMLStmt *stmt = static_cast<ObDMLStmt*>(basic_stmt);
SQL_LOG(DEBUG, "stmt", "stmt", *stmt);
SQL_LOG(DEBUG, "stmt success", "query", SJ(*stmt));
const ObGlobalHint &global_hint = stmt->get_query_ctx()->get_global_hint();
sql_ctx.session_info_->set_early_lock_release(global_hint.enable_lock_early_release_);
ObOptimizerContext optctx(sql_ctx.session_info_,
&result.get_exec_context(),
&result.get_exec_context().get_stmt_factory()->get_query_ctx()->sql_schema_guard_,
opt_stat_mgr_,
allocator,
&pctx->get_param_store(),
self_addr_,
GCTX.srv_rpc_proxy_,
global_hint,
*result.get_exec_context().get_expr_factory(),
stmt,
result.is_ps_protocol(),
result.get_exec_context().get_stmt_factory()->get_query_ctx());
optctx.set_aggregation_optimization_settings(aggregate_setting);
pctx->set_field_array(result.get_field_columns());
pctx->set_is_ps_protocol(result.is_ps_protocol());
bool is_restore = false;
uint64_t effective_tid = result.get_session().get_effective_tenant_id();
if (OB_FAIL(ret)) {
} else if (OB_ISNULL(sql_ctx.schema_guard_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("schema guard is null", K(ret));
} else if (OB_FAIL(sql_ctx.schema_guard_->check_tenant_is_restore(
effective_tid, is_restore))) {
LOG_WARN("fail to check if tenant is restore", K(ret), K(effective_tid));
} else if (is_restore) {
// 为避免物理恢复阶段系统表恢复过程中,SQL依赖需要恢复的统计信息表,
// 对恢复中租户,仅需获取缺省统计信息即可
optctx.set_use_default_stat();
}
ObOptimizer optimizer(optctx);
bool use_jit = false;
bool turn_on_jit = sql_ctx.need_late_compile_;
// if (OB_FAIL(ret)) {
// } else if (OB_FAIL(need_use_jit(turn_on_jit,
// query_hint.use_jit_policy_,
// *sql_ctx.session_info_,
// use_jit))) {
// use_jit = false;
// LOG_WARN("failed to check for needing jitted expr", K(ret));
// } else {
// // do nothing
// }
ObLogPlan *logical_plan = NULL;
ObPhysicalPlan *phy_plan = NULL;
// 内部session切租户时资源处理分离不彻底
// 当用户请求发送到一个没有对应租户资源的server上时,plan 内存算在了普通租户上,
// 但是计划挂在了sys租户的plan cache下面,导致plan_cache_stat表数据统计异常,
// 出现疑似内存泄漏实际上却没有泄漏的情况。这里处理为直接从plan cache
// 中取tenant id,这样计划分配的资源就算在了plan cache所对应的租户上
if (OB_NOT_NULL(result.get_session().get_plan_cache())) {
effective_tid = result.get_session().get_plan_cache()->get_tenant_id();
}
ObCacheObjGuard& guard = result.get_cache_obj_guard();
guard.init(PLAN_GEN_HANDLE);
if (OB_FAIL(ret)) {
} else if (OB_FAIL(ObCacheObjectFactory::alloc(guard,
ObLibCacheNameSpace::NS_CRSR,
effective_tid))) {
LOG_WARN("fail to alloc phy_plan", K(ret));
} else if (FALSE_IT(phy_plan = static_cast<ObPhysicalPlan*>(guard.get_cache_obj()))) {
// do nothing
} else if (OB_UNLIKELY(NULL == phy_plan)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("Failed to alloc physical plan from tc factory", K(ret));
} else {
// update is_use_jit flag
phy_plan->stat_.is_use_jit_ = use_jit;
phy_plan->stat_.enable_early_lock_release_ = sql_ctx.session_info_->get_early_lock_release();
// if phy_plan's tenant id, which refers the tenant who create this plan,
// not equal to current effective_tid, plan cache must be invalid
// and we shouldn't add this plan to plan cache.
if (NULL != pc_ctx) {
pc_ctx->should_add_plan_ = (effective_tid==phy_plan->get_tenant_id());
}
}
if (OB_SUCC(ret)) {
phy_plan->set_fetch_cur_time(stmt->get_fetch_cur_time());
phy_plan->set_stmt_type(stmt->get_stmt_type());
phy_plan->set_literal_stmt_type(stmt->get_query_ctx()->get_literal_stmt_type());
if (phy_plan->get_fetch_cur_time() && !pctx->has_cur_time()) {
pctx->set_cur_time(ObTimeUtility::current_time(), *(sql_ctx.session_info_));
}
pctx->set_last_trace_id(sql_ctx.session_info_->get_last_trace_id());
}
if (OB_FAIL(ret)) {
} else if (OB_FAIL(transform_stmt(&stmt->get_query_ctx()->sql_schema_guard_,
opt_stat_mgr_,
&self_addr_,
phy_plan,
result.get_exec_context(),
stmt))) { //rewrite stmt
LOG_WARN("Failed to transform stmt", K(ret));
} else if (OB_FALSE_IT(optctx.set_root_stmt(stmt))) {
} else if (OB_FAIL(optimize_stmt(optimizer, *(sql_ctx.session_info_),
*stmt, logical_plan))) { //gen logical plan
LOG_WARN("Failed to optimizer stmt", K(ret));
} else if (OB_FAIL(create_expr_constraints(*stmt->get_query_ctx(),
result.get_exec_context()))){
LOG_WARN("Failed to create expr constraints", K(ret));
} else if (OB_ISNULL(logical_plan)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid null logical plan", K(ret), K(logical_plan));
} else if (OB_FAIL(code_generate(sql_ctx, result, stmt,
stmt_need_privs, stmt_ora_need_privs,
audit_units,
logical_plan, phy_plan))) { //gen phy plan
LOG_WARN("Failed to generate phy plan", K(ret));
}
// memory debug for sql work arena
if (OB_UNLIKELY(result.get_mem_pool().total() > SQL_MEM_SIZE_LIMIT)) {
int64_t total_mem_used = result.get_mem_pool().total();
LOG_INFO("[SQL MEM USAGE] use too much memory", K(total_mem_used),
K(ObString(parse_result.input_sql_len_, parse_result.input_sql_)));
}
if (OB_FAIL(ret)) {
} else if (OB_ISNULL(stmt->get_query_ctx())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("query ctx is null", K(ret));
} else if (stmt::T_SELECT == stmt->get_stmt_type() &&
stmt::T_SHOW_PARAMETERS == stmt->get_query_ctx()->get_literal_stmt_type()) {
ObSelectStmt *select_stmt = static_cast<ObSelectStmt*>(stmt);
pctx->set_tenant_id(select_stmt->get_tenant_id());
pctx->set_show_seed(select_stmt->get_show_seed());
result.get_exec_context().reference_my_plan(phy_plan);
} else {
result.get_exec_context().reference_my_plan(phy_plan);
}
}
} else if (stmt::T_EXECUTE == basic_stmt->get_stmt_type()) {
if (OB_FAIL(handle_text_execute(basic_stmt, sql_ctx, result))) {
LOG_WARN("handle_text_execute failed", K(ret));
}
} else if (basic_stmt->is_dml_stmt()
|| basic_stmt->is_explain_stmt()
|| basic_stmt->is_help_stmt()) {
if (OB_FAIL(generate_plan(parse_result,
pc_ctx,
sql_ctx,
result,
mode,
basic_stmt,
stmt_need_privs,
stmt_ora_need_privs))) {
LOG_WARN("failed to generate plan", K(ret));
}
} else if (stmt::T_EXECUTE == basic_stmt->get_stmt_type()) {
if (OB_FAIL(handle_text_execute(basic_stmt, sql_ctx, result))) {
LOG_WARN("handle_text_execute failed", K(ret));
}
} else {
ObICmd *cmd = dynamic_cast<ObICmd*>(basic_stmt);
if (OB_UNLIKELY(NULL == cmd)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail cast basic stmt to cmd", K(ret));
} else {
ObICmd *cmd = dynamic_cast<ObICmd*>(basic_stmt);
if (OB_UNLIKELY(NULL == cmd)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail cast basic stmt to cmd", K(ret));
} else {
result.set_cmd(cmd);
result.get_session().set_cur_sql_id(sql_ctx.sql_id_);
if (!is_begin_commit_stmt
&& OB_FAIL(fill_result_set(result, &sql_ctx, mode, *basic_stmt))) {
LOG_WARN("Failed to fill result set", K(ret));
}
result.set_cmd(cmd);
result.get_session().set_cur_sql_id(sql_ctx.sql_id_);
if (!is_begin_commit_stmt
&& OB_FAIL(fill_result_set(result, &sql_ctx, mode, *basic_stmt))) {
LOG_WARN("Failed to fill result set", K(ret));
}
}
}
@ -2939,6 +2797,7 @@ int ObSql::generate_physical_plan(ParseResult &parse_result,
int tmp_ret = ret;
ObDMLStmt *stmt = static_cast<ObDMLStmt*>(basic_stmt);
uint64_t data_version = 0;
const uint64_t tenant_id = result.get_session().get_effective_tenant_id();
if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, data_version))) {
LOG_WARN("failed to get data version", K(ret));
} else if (data_version < DATA_VERSION_4_1_0_0 && stmt->get_ref_obj_table()->is_inited()) {
@ -2954,6 +2813,233 @@ int ObSql::generate_physical_plan(ParseResult &parse_result,
return ret;
}
int ObSql::generate_plan(ParseResult &parse_result,
ObPlanCacheCtx *pc_ctx,
ObSqlCtx &sql_ctx,
ObResultSet &result,
const PlanCacheMode mode,
ObStmt *basic_stmt,
ObStmtNeedPrivs &stmt_need_privs,
ObStmtOraNeedPrivs &stmt_ora_need_privs)
{
int ret = OB_SUCCESS;
uint64_t aggregate_setting = 0;
ObPhysicalPlanCtx *pctx = result.get_exec_context().get_physical_plan_ctx();
bool allow_audit = false;
ObArray<ObAuditUnit> audit_units;
if (OB_ISNULL(pctx) || OB_ISNULL(basic_stmt) ||
OB_ISNULL(result.get_exec_context().get_expr_factory())) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("Physical plan ctx should not be NULL", K(ret));
} else if (OB_ISNULL(result.get_exec_context().get_stmt_factory()->get_query_ctx())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("query ctx is null", K(ret));
} else if (OB_FAIL(fill_result_set(result, &sql_ctx, mode, *basic_stmt))) {
LOG_WARN("Failed to fill result set", K(ret));
} else if (OB_FAIL(sql_ctx.session_info_->get_sys_variable(
share::SYS_VAR__AGGREGATION_OPTIMIZATION_SETTINGS,
aggregate_setting))) {
LOG_WARN("failed to get aggregate setting", K(ret));
} else {
ObDMLStmt *stmt = static_cast<ObDMLStmt*>(basic_stmt);
SQL_LOG(DEBUG, "stmt", "stmt", *stmt);
SQL_LOG(DEBUG, "stmt success", "query", SJ(*stmt));
const ObGlobalHint &global_hint = stmt->get_query_ctx()->get_global_hint();
sql_ctx.session_info_->set_early_lock_release(global_hint.enable_lock_early_release_);
ObOptimizerContext optctx(sql_ctx.session_info_,
&result.get_exec_context(),
&result.get_exec_context().get_stmt_factory()->get_query_ctx()->sql_schema_guard_,
opt_stat_mgr_,
result.get_mem_pool(),
&pctx->get_param_store(),
self_addr_,
GCTX.srv_rpc_proxy_,
global_hint,
*result.get_exec_context().get_expr_factory(),
stmt,
result.is_ps_protocol(),
result.get_exec_context().get_stmt_factory()->get_query_ctx());
optctx.set_aggregation_optimization_settings(aggregate_setting);
pctx->set_field_array(result.get_field_columns());
pctx->set_is_ps_protocol(result.is_ps_protocol());
bool is_restore = false;
uint64_t effective_tid = result.get_session().get_effective_tenant_id();
if (OB_FAIL(ret)) {
} else if (OB_ISNULL(sql_ctx.schema_guard_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("schema guard is null", K(ret));
} else if (OB_FAIL(sql_ctx.schema_guard_->check_tenant_is_restore(
effective_tid, is_restore))) {
LOG_WARN("fail to check if tenant is restore", K(ret), K(effective_tid));
} else if (is_restore) {
// 为避免物理恢复阶段系统表恢复过程中,SQL依赖需要恢复的统计信息表,
// 对恢复中租户,仅需获取缺省统计信息即可
optctx.set_use_default_stat();
}
ObOptimizer optimizer(optctx);
bool use_jit = false;
bool turn_on_jit = sql_ctx.need_late_compile_;
// if (OB_FAIL(ret)) {
// } else if (OB_FAIL(need_use_jit(turn_on_jit,
// query_hint.use_jit_policy_,
// *sql_ctx.session_info_,
// use_jit))) {
// use_jit = false;
// LOG_WARN("failed to check for needing jitted expr", K(ret));
// } else {
// // do nothing
// }
ObLogPlan *logical_plan = NULL;
ObPhysicalPlan *phy_plan = NULL;
// 内部session切租户时资源处理分离不彻底
// 当用户请求发送到一个没有对应租户资源的server上时,plan 内存算在了普通租户上,
// 但是计划挂在了sys租户的plan cache下面,导致plan_cache_stat表数据统计异常,
// 出现疑似内存泄漏实际上却没有泄漏的情况。这里处理为直接从plan cache
// 中取tenant id,这样计划分配的资源就算在了plan cache所对应的租户上
if (OB_NOT_NULL(result.get_session().get_plan_cache())) {
effective_tid = result.get_session().get_plan_cache()->get_tenant_id();
}
ObCacheObjGuard& guard = result.get_cache_obj_guard();
guard.init(PLAN_GEN_HANDLE);
if (OB_FAIL(ret)) {
} else if (OB_FAIL(ObCacheObjectFactory::alloc(guard,
ObLibCacheNameSpace::NS_CRSR,
effective_tid))) {
LOG_WARN("fail to alloc phy_plan", K(ret));
} else if (FALSE_IT(phy_plan = static_cast<ObPhysicalPlan*>(guard.get_cache_obj()))) {
// do nothing
} else if (OB_UNLIKELY(NULL == phy_plan)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("Failed to alloc physical plan from tc factory", K(ret));
} else {
// update is_use_jit flag
phy_plan->stat_.is_use_jit_ = use_jit;
phy_plan->stat_.enable_early_lock_release_ = sql_ctx.session_info_->get_early_lock_release();
// if phy_plan's tenant id, which refers the tenant who create this plan,
// not equal to current effective_tid, plan cache must be invalid
// and we shouldn't add this plan to plan cache.
if (NULL != pc_ctx) {
pc_ctx->should_add_plan_ = (effective_tid==phy_plan->get_tenant_id());
}
}
if (OB_SUCC(ret)) {
phy_plan->set_fetch_cur_time(stmt->get_fetch_cur_time());
phy_plan->set_stmt_type(stmt->get_stmt_type());
phy_plan->set_literal_stmt_type(stmt->get_query_ctx()->get_literal_stmt_type());
if (phy_plan->get_fetch_cur_time() && !pctx->has_cur_time()) {
pctx->set_cur_time(ObTimeUtility::current_time(), *(sql_ctx.session_info_));
}
pctx->set_last_trace_id(sql_ctx.session_info_->get_last_trace_id());
}
ObSQLSessionInfo *session_info = result.get_exec_context().get_my_session();
BEGIN_OPT_TRACE(session_info, ObString(strlen(sql_ctx.sql_id_), sql_ctx.sql_id_));
OPT_TRACE_ENV;
OPT_TRACE_SESSION_INFO;
OPT_TRACE_PARAMETERS;
OPT_TRACE_TITLE("CURRENT SQL TEXT");
OPT_TRACE("sql_id =", ObString(strlen(sql_ctx.sql_id_), sql_ctx.sql_id_));
OPT_TRACE(ObString(parse_result.input_sql_len_, parse_result.input_sql_));
if (OB_FAIL(ret)) {
} else if (OB_FAIL(transform_stmt(&stmt->get_query_ctx()->sql_schema_guard_,
opt_stat_mgr_,
&self_addr_,
phy_plan,
result.get_exec_context(),
stmt))) { //rewrite stmt
LOG_WARN("Failed to transform stmt", K(ret));
} else if (OB_FALSE_IT(optctx.set_root_stmt(stmt))) {
} else if (OB_FAIL(optimize_stmt(optimizer, *(sql_ctx.session_info_),
*stmt, logical_plan))) { //gen logical plan
LOG_WARN("Failed to optimizer stmt", K(ret));
} else if (OB_FAIL(create_expr_constraints(*stmt->get_query_ctx(),
result.get_exec_context()))){
LOG_WARN("Failed to create expr constraints", K(ret));
} else if (OB_ISNULL(logical_plan)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid null logical plan", K(ret), K(logical_plan));
} else if (OB_FAIL(code_generate(sql_ctx, result, stmt,
stmt_need_privs,
stmt_ora_need_privs,
audit_units,
logical_plan, phy_plan))) { //gen phy plan
LOG_WARN("Failed to genenrate phy plan", K(ret));
} else if (OB_FAIL(prepare_outline_for_phy_plan(logical_plan,
phy_plan))) {
LOG_WARN("failed to prepare outline for phy plan", K(ret));
}
END_OPT_TRACE(session_info);
if (OB_SUCC(ret) && session_info->is_user_session()) {
ObSqlPlan sql_plan(result.get_mem_pool());
sql_plan.set_session_info(session_info);
ObString sql_id(strlen(sql_ctx.sql_id_), sql_ctx.sql_id_);
if (!stmt->is_explain_stmt() && !stmt->is_help_stmt()) {
if (OB_FAIL(sql_plan.store_sql_plan(logical_plan,
phy_plan->get_plan_id(),
phy_plan->get_plan_hash_value(),
sql_id))) {
LOG_WARN("failed to store sql plan", K(ret));
} else {
phy_plan->set_record_plan_info(true);
}
}
}
// memory debug for sql work arena
if (OB_UNLIKELY(result.get_mem_pool().total() > SQL_MEM_SIZE_LIMIT)) {
int64_t total_mem_used = result.get_mem_pool().total();
LOG_INFO("[SQL MEM USAGE] use too much memory", K(total_mem_used),
K(ObString(parse_result.input_sql_len_, parse_result.input_sql_)));
}
if (OB_FAIL(ret)) {
} else if (OB_ISNULL(stmt->get_query_ctx())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("query ctx is null", K(ret));
} else if (stmt::T_SELECT == stmt->get_stmt_type() &&
stmt::T_SHOW_PARAMETERS == stmt->get_query_ctx()->get_literal_stmt_type()) {
ObSelectStmt *select_stmt = static_cast<ObSelectStmt*>(stmt);
pctx->set_tenant_id(select_stmt->get_tenant_id());
pctx->set_show_seed(select_stmt->get_show_seed());
result.get_exec_context().reference_my_plan(phy_plan);
} else {
result.get_exec_context().reference_my_plan(phy_plan);
}
}
return ret;
}
int ObSql::prepare_outline_for_phy_plan(ObLogPlan *logical_plan,
ObPhysicalPlan *phy_plan)
{
int ret = OB_SUCCESS;
void *tmp_ptr = NULL;
char *buf = NULL;
if (OB_ISNULL(logical_plan) || OB_ISNULL(phy_plan)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail to get log plan", K(ret), K(logical_plan));
} else if (OB_UNLIKELY(NULL == (tmp_ptr = phy_plan->get_allocator().alloc(OB_MAX_SQL_LENGTH)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("fail to alloc memory", K(ret));
} else if (FALSE_IT(buf = static_cast<char *>(tmp_ptr))) {
} else {
PlanText plan_text;
plan_text.buf_ = buf;
plan_text.buf_len_ = OB_MAX_SQL_LENGTH;
if (OB_FAIL(ObSqlPlan::get_plan_outline_info_one_line(plan_text, logical_plan))) {
LOG_WARN("failed to get plan outline info", K(ret));
} else {
phy_plan->stat_.outline_data_.assign_ptr(buf, static_cast<ObString::obstr_size_t>(plan_text.pos_));
}
}
return ret;
}
// stmt 全量 const folding.
int ObSql::calc_pre_calculable_exprs(ObExecContext &exec_ctx,
ObDMLStmt &stmt,
@ -3073,6 +3159,7 @@ int ObSql::transform_stmt(ObSqlSchemaGuard *sql_schema_guard,
}
NG_TRACE(transform_begin);
OPT_TRACE_TITLE("START TRANSFORM");
if (OB_SUCC(ret) && transform_stmt->is_valid_transform_stmt()) {
ObTransformerImpl transformer(&trans_ctx);
if (OB_FAIL(transformer.transform(transform_stmt))) {
@ -3099,6 +3186,11 @@ int ObSql::transform_stmt(ObSqlSchemaGuard *sql_schema_guard,
}
}
if (OB_SUCC(ret)) {
OPT_TRACE("after transform, sql is\n", transform_stmt);
OPT_TRACE_TIME_USED;
OPT_TRACE_MEM_USED;
}
transformer_mem_usage = exec_ctx.get_allocator().total() - last_mem_usage;
LOG_DEBUG("SQL MEM USAGE", K(transformer_mem_usage), K(last_mem_usage));
return ret;
@ -3115,13 +3207,20 @@ int ObSql::optimize_stmt(
logical_plan = NULL;
LOG_TRACE("stmt to generate plan", K(stmt));
NG_TRACE(optimize_begin);
OPT_TRACE_TITLE("START GENERATE PLAN");
if (OB_FAIL(optimizer.optimize(stmt, logical_plan))) {
LOG_WARN("Failed to optimize logical plan", K(ret));
// do nothing(plan will be destructed in result set)
} else if (OB_FAIL(optimizer.update_column_usage_infos())) {
LOG_WARN("failed to update column usage infos", K(ret));
} else if (OB_ISNULL(logical_plan)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null log plan", K(ret));
} else {
LOG_TRACE("logical plan", KPC(logical_plan));
OPT_TRACE_TIME_USED;
OPT_TRACE_MEM_USED;
OPT_TRACE(logical_plan);
}
return ret;