From b3e8f8f67bc8d87902adbe06f5612cad71f01080 Mon Sep 17 00:00:00 2001 From: wjhh2008 Date: Fri, 21 Jul 2023 09:48:58 +0000 Subject: [PATCH] [CP] enhance GTT --- deps/oblib/src/lib/ob_name_def.h | 1 + src/objit/include/objit/common/ob_item_type.h | 3 +- src/observer/mysql/obmp_base.cpp | 3 + src/sql/CMakeLists.txt | 1 + .../code_generator/ob_static_engine_cg.cpp | 34 +++--- src/sql/engine/cmd/ob_table_executor.cpp | 7 +- .../engine/expr/ob_expr_eval_functions.cpp | 5 +- .../engine/expr/ob_expr_operator_factory.cpp | 2 + .../engine/expr/ob_expr_temp_table_ssid.cpp | 92 ++++++++++++++++ src/sql/engine/expr/ob_expr_temp_table_ssid.h | 45 ++++++++ src/sql/engine/ob_physical_plan.cpp | 8 +- src/sql/engine/ob_physical_plan.h | 14 ++- src/sql/ob_sql.cpp | 39 ++++--- src/sql/ob_sql_utils.h | 19 ++++ src/sql/plan_cache/ob_plan_cache_value.cpp | 3 +- .../resolver/ddl/ob_create_table_resolver.cpp | 2 + .../resolver/ddl/ob_create_table_resolver.h | 1 + .../ddl/ob_truncate_table_resolver.cpp | 1 + .../resolver/ddl/ob_truncate_table_stmt.cpp | 7 +- src/sql/resolver/ddl/ob_truncate_table_stmt.h | 3 + src/sql/resolver/dml/ob_del_upd_resolver.cpp | 104 +++++++++++------- src/sql/resolver/dml/ob_del_upd_resolver.h | 2 + src/sql/resolver/dml/ob_insert_resolver.cpp | 1 + src/sql/resolver/expr/ob_raw_expr.cpp | 1 + src/sql/rewrite/ob_transform_pre_process.cpp | 93 ++++++++++------ src/sql/rewrite/ob_transform_pre_process.h | 3 +- src/sql/session/ob_sql_session_info.cpp | 99 +++++++++++------ src/sql/session/ob_sql_session_info.h | 15 +++ 28 files changed, 454 insertions(+), 154 deletions(-) create mode 100644 src/sql/engine/expr/ob_expr_temp_table_ssid.cpp create mode 100644 src/sql/engine/expr/ob_expr_temp_table_ssid.h diff --git a/deps/oblib/src/lib/ob_name_def.h b/deps/oblib/src/lib/ob_name_def.h index 5dccd57232..6a4a984b10 100644 --- a/deps/oblib/src/lib/ob_name_def.h +++ b/deps/oblib/src/lib/ob_name_def.h @@ -1062,4 +1062,5 @@ #define N_XMLCAST "xmlcast" #define N_UPDATEXML "updatexml" #define N_NLS_INITCAP "nls_initcap" +#define N_TEMP_TABLE_SSID "temp_table_ssid" #endif //OCEANBASE_LIB_OB_NAME_DEF_H_ diff --git a/src/objit/include/objit/common/ob_item_type.h b/src/objit/include/objit/common/ob_item_type.h index 4022b5164c..c7258fc737 100755 --- a/src/objit/include/objit/common/ob_item_type.h +++ b/src/objit/include/objit/common/ob_item_type.h @@ -212,8 +212,7 @@ typedef enum ObItemType T_OP_AGG_MUL = 184, T_OP_AGG_DIV = 185, T_OP_OUTPUT_PACK = 186, - T_FUN_TEMP_TABLE_SSID = 187, - + T_FUN_GET_TEMP_TABLE_SESSID = 187, ///< @note add new operator before this line // system functions diff --git a/src/observer/mysql/obmp_base.cpp b/src/observer/mysql/obmp_base.cpp index 17cdcac0cd..d517325e70 100644 --- a/src/observer/mysql/obmp_base.cpp +++ b/src/observer/mysql/obmp_base.cpp @@ -281,6 +281,9 @@ int ObMPBase::create_session(ObSMConnection *conn, ObSQLSessionInfo *&sess_info) } else { sess_info->set_ssl_cipher(""); } + + sess_info->gen_gtt_session_scope_unique_id(); + sess_info->gen_gtt_trans_scope_unique_id(); } } return ret; diff --git a/src/sql/CMakeLists.txt b/src/sql/CMakeLists.txt index 2fe76cad50..672e9d7441 100644 --- a/src/sql/CMakeLists.txt +++ b/src/sql/CMakeLists.txt @@ -642,6 +642,7 @@ ob_set_subtarget(ob_sql engine_expr engine/expr/ob_expr_extract_xml.cpp engine/expr/ob_expr_xmlcast.cpp engine/expr/ob_expr_update_xml.cpp + engine/expr/ob_expr_temp_table_ssid.cpp ) ob_set_subtarget(ob_sql engine_join diff --git a/src/sql/code_generator/ob_static_engine_cg.cpp b/src/sql/code_generator/ob_static_engine_cg.cpp index 26e2aa4134..5b04ba2e66 100644 --- a/src/sql/code_generator/ob_static_engine_cg.cpp +++ b/src/sql/code_generator/ob_static_engine_cg.cpp @@ -6747,26 +6747,27 @@ int ObStaticEngineCG::set_other_properties(const ObLogPlan &log_plan, ObPhysical LOG_DEBUG("is contain global index or dep base table", K(has_dep_table)); phy_plan.set_is_dep_base_table(has_dep_table); + ObArray gtt_trans_scope_ids; + ObArray gtt_session_scope_ids; for (int64_t i = 0; OB_SUCC(ret) && i < dependency_table->count(); i++) { if (DEPENDENCY_TABLE == dependency_table->at(i).object_type_) { const ObTableSchema *table_schema = NULL; - if (OB_FAIL(schema_guard->get_table_schema( - MTL_ID(), - dependency_table->at(i).get_object_id(), - table_schema))) { - LOG_WARN("fail to get table schema", K(ret), "table_id", dependency_table->at(i).get_object_id()); + int64_t object_id = dependency_table->at(i).get_object_id(); + if (OB_FAIL(schema_guard->get_table_schema(my_session->get_effective_tenant_id(), + object_id, table_schema))) { + LOG_WARN("fail to get table schema", K(ret), K(object_id)); } else if (OB_ISNULL(table_schema)) { ret = OB_TABLE_NOT_EXIST; - LOG_WARN("fail to get table schema", K(ret), "table_id", dependency_table->at(i).get_object_id()); + LOG_WARN("fail to get table schema", K(ret), K(object_id)); } else { if (table_schema->is_oracle_trx_tmp_table()) { - phy_plan.set_contain_oracle_trx_level_temporary_table(); - } - if (table_schema->is_oracle_sess_tmp_table()) { - phy_plan.set_contain_oracle_session_level_temporary_table(); - } - if (table_schema->is_mysql_tmp_table()) { - phy_plan.set_session_id(table_schema->get_session_id()); + if (OB_FAIL(gtt_trans_scope_ids.push_back(object_id))) { + LOG_WARN("fail to push back", K(ret)); + } + } else if (table_schema->is_oracle_sess_tmp_table()) { + if (OB_FAIL(gtt_session_scope_ids.push_back(object_id))) { + LOG_WARN("fail to push back", K(ret)); + } } LOG_DEBUG("plan contain temporary table", "trx level", table_schema->is_oracle_trx_tmp_table(), @@ -6774,6 +6775,13 @@ int ObStaticEngineCG::set_other_properties(const ObLogPlan &log_plan, ObPhysical } } } + if (OB_SUCC(ret)) { + if (OB_FAIL(phy_plan.get_gtt_trans_scope_ids().assign(gtt_trans_scope_ids))) { + LOG_WARN("fail to assign array", K(ret)); + } else if (OB_FAIL(phy_plan.get_gtt_session_scope_ids().assign(gtt_session_scope_ids))) { + LOG_WARN("fail to assign array", K(ret)); + } + } } if (OB_SUCC(ret)) { int64_t tenant_schema_version = OB_INVALID_VERSION; diff --git a/src/sql/engine/cmd/ob_table_executor.cpp b/src/sql/engine/cmd/ob_table_executor.cpp index 8f34cdbb31..2273a9b02d 100644 --- a/src/sql/engine/cmd/ob_table_executor.cpp +++ b/src/sql/engine/cmd/ob_table_executor.cpp @@ -2199,6 +2199,8 @@ int ObTruncateTableExecutor::execute(ObExecContext &ctx, ObTruncateTableStmt &st K(res)); } } + } else if (stmt.get_oracle_temp_table_type() == share::schema::TMP_TABLE_ORA_TRX) { + //do nothing } else { ObSqlString sql; int64_t affect_rows = 0; @@ -2206,14 +2208,15 @@ int ObTruncateTableExecutor::execute(ObExecContext &ctx, ObTruncateTableStmt &st uint64_t tenant_id = stmt.get_tenant_id(); ObString db_name = stmt.get_database_name(); ObString tab_name = stmt.get_table_name(); - int64_t session_id = my_session->get_sessid_for_table(); + uint64_t unique_id = my_session->get_gtt_session_scope_unique_id(); + if (OB_FAIL(oracle_sql_proxy.init(GCTX.sql_proxy_->get_pool()))) { LOG_WARN("init oracle sql proxy failed", K(ret)); } else if (OB_FAIL(sql.assign_fmt("DELETE FROM \"%.*s\".\"%.*s\" WHERE " "%s = %ld", db_name.length(), db_name.ptr(), tab_name.length(), tab_name.ptr(), - OB_HIDDEN_SESSION_ID_COLUMN_NAME, session_id))) { + OB_HIDDEN_SESSION_ID_COLUMN_NAME, unique_id))) { LOG_WARN("fail to assign sql", K(ret)); } else if (OB_FAIL(oracle_sql_proxy.write(tenant_id, sql.ptr(), affect_rows))) { LOG_WARN("execute sql failed", K(ret), K(sql), K(affect_rows)); diff --git a/src/sql/engine/expr/ob_expr_eval_functions.cpp b/src/sql/engine/expr/ob_expr_eval_functions.cpp index 5809d867ba..f6344052eb 100644 --- a/src/sql/engine/expr/ob_expr_eval_functions.cpp +++ b/src/sql/engine/expr/ob_expr_eval_functions.cpp @@ -332,6 +332,7 @@ #include "ob_expr_uniform.h" #include "ob_expr_prefix_pattern.h" #include "ob_expr_initcap.h" +#include "ob_expr_temp_table_ssid.h" namespace oceanbase { @@ -1033,8 +1034,8 @@ static ObExpr::EvalFunc g_expr_eval_functions[] = { ObExprUpdateXml::eval_update_xml, /* 603 */ ObExprJoinFilter::eval_range_filter, /* 604 */ ObExprJoinFilter::eval_in_filter, /* 605 */ - ObExprCurrentScn::eval_current_scn /* 606 */ - //ObExprTempTableSSID::calc_temp_table_ssid, /* 607 */ + ObExprCurrentScn::eval_current_scn, /* 606 */ + ObExprTempTableSSID::calc_temp_table_ssid, /* 607 */ }; static ObExpr::EvalBatchFunc g_expr_eval_batch_functions[] = { diff --git a/src/sql/engine/expr/ob_expr_operator_factory.cpp b/src/sql/engine/expr/ob_expr_operator_factory.cpp index 2512b69095..76921f1ca0 100644 --- a/src/sql/engine/expr/ob_expr_operator_factory.cpp +++ b/src/sql/engine/expr/ob_expr_operator_factory.cpp @@ -401,6 +401,7 @@ #include "sql/engine/expr/ob_expr_xml_serialize.h" #include "sql/engine/expr/ob_expr_xmlcast.h" #include "sql/engine/expr/ob_expr_update_xml.h" +#include "sql/engine/expr/ob_expr_temp_table_ssid.h" using namespace oceanbase::common; namespace oceanbase @@ -1305,6 +1306,7 @@ void ObExprOperatorFactory::register_expr_operators() REG_OP_ORCL(ObExprXmlSerialize); REG_OP_ORCL(ObExprXmlcast); REG_OP_ORCL(ObExprUpdateXml); + REG_OP_ORCL(ObExprTempTableSSID); } bool ObExprOperatorFactory::is_expr_op_type_valid(ObExprOperatorType type) diff --git a/src/sql/engine/expr/ob_expr_temp_table_ssid.cpp b/src/sql/engine/expr/ob_expr_temp_table_ssid.cpp new file mode 100644 index 0000000000..9e7932a4f3 --- /dev/null +++ b/src/sql/engine/expr/ob_expr_temp_table_ssid.cpp @@ -0,0 +1,92 @@ +/** + * 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. + */ + +// (C) Copyright 2011-2023 Alibaba Inc. All Rights Reserved. +// Authors: +// jim.wjh <> +// +#define USING_LOG_PREFIX SQL_ENG +#include "ob_expr_temp_table_ssid.h" +#include "sql/session/ob_sql_session_info.h" +#include "sql/engine/ob_exec_context.h" + +using namespace oceanbase::common; +using namespace oceanbase::sql; + +namespace oceanbase +{ +namespace sql +{ + +ObExprTempTableSSID::ObExprTempTableSSID(ObIAllocator &alloc) + : ObFuncExprOperator(alloc, T_FUN_GET_TEMP_TABLE_SESSID, N_TEMP_TABLE_SSID, 1, NOT_VALID_FOR_GENERATED_COL, NOT_ROW_DIMENSION) +{ +} + +ObExprTempTableSSID::~ObExprTempTableSSID() +{ +} + +int ObExprTempTableSSID::calc_result_type1(ObExprResType &type, ObExprResType &type1, ObExprTypeCtx &type_ctx) const +{ + UNUSED(type1); + UNUSED(type_ctx); + int ret = OB_SUCCESS; + type.set_int(); + type.set_precision(ObAccuracy::DDL_DEFAULT_ACCURACY[ObIntType].precision_); + type.set_scale(DEFAULT_SCALE_FOR_INTEGER); + type1.set_calc_type(ObIntType); + return ret; +} + +int ObExprTempTableSSID::calc_temp_table_ssid(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res) +{ + int ret = OB_SUCCESS; + ObDatum *param = NULL; + if (OB_ISNULL(ctx.exec_ctx_.get_my_session())) { + ret = OB_ERR_UNDEFINED; + } else if (OB_FAIL(expr.args_[0]->eval(ctx, param))) { + LOG_WARN("fail to eval param", K(ret)); + } else if (expr.args_[0]->datum_meta_.type_ != ObIntType) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid object", K(ret)); + } else { + switch (param->get_int()) { + case GTT_SESSION_SCOPE: + res.set_int(ctx.exec_ctx_.get_my_session()->get_gtt_session_scope_unique_id()); + break; + case GTT_TRANS_SCOPE: + res.set_int(ctx.exec_ctx_.get_my_session()->get_gtt_trans_scope_unique_id()); + break; + default: + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid object", K(ret), KPC(param)); + } + LOG_DEBUG("get result", K(res.get_int())); + } + return ret; +} + +int ObExprTempTableSSID::cg_expr( + ObExprCGCtx &op_cg_ctx, + const ObRawExpr &raw_expr, + ObExpr &rt_expr) const +{ + UNUSED(op_cg_ctx); + UNUSED(raw_expr); + int ret = OB_SUCCESS; + rt_expr.eval_func_ = calc_temp_table_ssid; + return ret; +} + +} +} diff --git a/src/sql/engine/expr/ob_expr_temp_table_ssid.h b/src/sql/engine/expr/ob_expr_temp_table_ssid.h new file mode 100644 index 0000000000..aa9e7c5518 --- /dev/null +++ b/src/sql/engine/expr/ob_expr_temp_table_ssid.h @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase CE is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +// Copyright (c) 2011-2023 Alibaba Inc. All Rights Reserved. +// Author: +// jim.wjh <> + + +#ifndef _OB_EXPR_TEMP_TABLE_SSID_H +#define _OB_EXPR_TEMP_TABLE_SSID_H +#include "sql/engine/expr/ob_expr_operator.h" + +namespace oceanbase +{ +namespace sql +{ + +class ObExprTempTableSSID : public ObFuncExprOperator +{ +public: + enum {GTT_SESSION_SCOPE, GTT_TRANS_SCOPE, MAX_GTT_SCOPTE}; +public: + explicit ObExprTempTableSSID(common::ObIAllocator &alloc); + virtual ~ObExprTempTableSSID(); + int calc_result_type1(ObExprResType &type, ObExprResType &type1, common::ObExprTypeCtx &type_ctx) const override; + int cg_expr(ObExprCGCtx &op_cg_ctx, const ObRawExpr &raw_expr, ObExpr &rt_expr) const override; + static int calc_temp_table_ssid(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res); + +private: + DISALLOW_COPY_AND_ASSIGN(ObExprTempTableSSID); +}; + +} +} + +#endif // _OB_EXPR_TEMP_TABLE_SSID_H diff --git a/src/sql/engine/ob_physical_plan.cpp b/src/sql/engine/ob_physical_plan.cpp index 265843193e..c75674b774 100644 --- a/src/sql/engine/ob_physical_plan.cpp +++ b/src/sql/engine/ob_physical_plan.cpp @@ -81,6 +81,8 @@ ObPhysicalPlan::ObPhysicalPlan(MemoryContext &mem_context /* = CURRENT_CONTEXT * session_id_(0), contain_oracle_trx_level_temporary_table_(false), contain_oracle_session_level_temporary_table_(false), + gtt_session_scope_ids_(allocator_), + gtt_trans_scope_ids_(allocator_), concurrent_num_(0), max_concurrent_num_(ObMaxConcurrentParam::UNLIMITED), table_locations_(allocator_), @@ -179,6 +181,8 @@ void ObPhysicalPlan::reset() session_id_ = 0; contain_oracle_trx_level_temporary_table_ = false; contain_oracle_session_level_temporary_table_ = false; + gtt_session_scope_ids_.reset(); + gtt_trans_scope_ids_.reset(); concurrent_num_ = 0; max_concurrent_num_ = ObMaxConcurrentParam::UNLIMITED; is_update_uniq_index_ = false; @@ -769,7 +773,9 @@ OB_SERIALIZE_MEMBER(ObPhysicalPlan, need_record_plan_info_, enable_append_, append_table_id_, - is_enable_px_fast_reclaim_); + is_enable_px_fast_reclaim_, + gtt_session_scope_ids_, + gtt_trans_scope_ids_); int ObPhysicalPlan::set_table_locations(const ObTablePartitionInfoArray &infos, ObSchemaGetterGuard &schema_guard) diff --git a/src/sql/engine/ob_physical_plan.h b/src/sql/engine/ob_physical_plan.h index 38aec2a1e7..c5d2f7629e 100644 --- a/src/sql/engine/ob_physical_plan.h +++ b/src/sql/engine/ob_physical_plan.h @@ -274,10 +274,10 @@ public: bool has_nested_sql() const { return has_nested_sql_; } void set_session_id(uint64_t v) { session_id_ = v; } uint64_t get_session_id() const { return session_id_; } - void set_contain_oracle_trx_level_temporary_table() { contain_oracle_trx_level_temporary_table_ = true; } - bool is_contain_oracle_trx_level_temporary_table() const { return contain_oracle_trx_level_temporary_table_; } - void set_contain_oracle_session_level_temporary_table() { contain_oracle_session_level_temporary_table_ = true; } - bool is_contain_oracle_session_level_temporary_table() const { return contain_oracle_session_level_temporary_table_; } + common::ObIArray &get_gtt_trans_scope_ids() { return gtt_trans_scope_ids_; } + common::ObIArray &get_gtt_session_scope_ids() { return gtt_session_scope_ids_; } + bool is_contain_oracle_trx_level_temporary_table() const { return gtt_trans_scope_ids_.count() > 0; } + bool is_contain_oracle_session_level_temporary_table() const { return gtt_session_scope_ids_.count() > 0; } bool contains_temp_table() const {return 0 != session_id_; } void set_returning(bool is_returning) { is_returning_ = is_returning; } bool is_returning() const { return is_returning_; } @@ -562,8 +562,10 @@ private: bool contain_table_scan_; //是否包含主键扫描 bool has_nested_sql_; // 是否可能执行嵌套语句 uint64_t session_id_; //当计划包含临时表时记录table_schema->session_id, 用于判断计划能否重用 - bool contain_oracle_trx_level_temporary_table_; - bool contain_oracle_session_level_temporary_table_; + bool contain_oracle_trx_level_temporary_table_; // not used + bool contain_oracle_session_level_temporary_table_; // not used + common::ObFixedArray gtt_session_scope_ids_; + common::ObFixedArray gtt_trans_scope_ids_; //for outline use ObOutlineState outline_state_; diff --git a/src/sql/ob_sql.cpp b/src/sql/ob_sql.cpp index 59ddfae6d2..50b11320a8 100644 --- a/src/sql/ob_sql.cpp +++ b/src/sql/ob_sql.cpp @@ -4465,24 +4465,27 @@ int ObSql::after_get_plan(ObPlanCacheCtx &pc_ctx, } } } - if (OB_SUCC(ret) && NULL != phy_plan && !session.get_is_deserialized()) { - bool has_session_tmp_table = phy_plan->is_contain_oracle_session_level_temporary_table() - || phy_plan->contains_temp_table(); - bool has_txn_tmp_table = phy_plan->is_contain_oracle_trx_level_temporary_table(); - if (has_session_tmp_table || has_txn_tmp_table) { - if (!session.is_inner() && session.is_txn_free_route_temp()) { - ret = OB_TRANS_FREE_ROUTE_NOT_SUPPORTED; - LOG_WARN("access temp table is supported to be executed on txn temporary node", KR(ret), K(session.get_txn_free_route_ctx())); - } else if (has_session_tmp_table) { - bool is_already_set = false; - if (OB_FAIL(session.get_session_temp_table_used(is_already_set))) { - LOG_WARN("fail to get session temp table used", K(ret)); - } else if (is_already_set) { - //do nothing - } else if (OB_FAIL(session.set_session_temp_table_used(true))) { - LOG_WARN("fail to set session temp table used", K(ret)); - } - LOG_DEBUG("plan contain oracle session level temporary table detected", K(is_already_set)); + if (OB_SUCC(ret) && NULL != phy_plan && !session.get_is_deserialized() && !session.is_inner()) { + if (phy_plan->is_contain_oracle_session_level_temporary_table() + || phy_plan->is_contain_oracle_trx_level_temporary_table() + || phy_plan->contains_temp_table()) { + bool is_already_set = false; + if (OB_FAIL(session.get_session_temp_table_used(is_already_set))) { + LOG_WARN("fail to get session temp table used", K(ret)); + } else if (is_already_set) { + //do nothing + } else if (OB_FAIL(session.set_session_temp_table_used(true))) { + LOG_WARN("fail to set session temp table used", K(ret)); + } + LOG_DEBUG("plan contain oracle session level temporary table detected", K(is_already_set)); + } + if (OB_SUCC(ret)) { + if (OB_FAIL(append_array_no_dup(session.get_gtt_session_scope_ids(), + phy_plan->get_gtt_session_scope_ids()))) { + LOG_WARN("fail to append array", K(ret)); + } else if (OB_FAIL(append_array_no_dup(session.get_gtt_trans_scope_ids(), + phy_plan->get_gtt_trans_scope_ids()))) { + LOG_WARN("fail to append array", K(ret)); } } } diff --git a/src/sql/ob_sql_utils.h b/src/sql/ob_sql_utils.h index 9ad5d82f12..b6aba48a20 100644 --- a/src/sql/ob_sql_utils.h +++ b/src/sql/ob_sql_utils.h @@ -627,6 +627,25 @@ public: static int print_identifier_require_quotes(ObCollationType collation_type, const ObString &ident, bool &require); + + static int64_t get_next_ts(int64_t &old_ts) { + int64_t next_ts = common::OB_INVALID_TIMESTAMP; + + while (true) { + int64_t origin_ts = ATOMIC_LOAD(&old_ts); + int64_t now = ObClockGenerator::getClock(); + next_ts = (now > origin_ts) ? now : (origin_ts + 1); + if (origin_ts == ATOMIC_VCAS(&old_ts, origin_ts, next_ts)) { + break; + } else { + PAUSE(); + } + }; + return next_ts; + } + static int64_t combine_server_id(int64_t ts, uint64_t server_id) { + return (ts & ((1LL << 43) - 1LL)) | ((server_id & 0xFFFF) << 48); + } private: static int check_ident_name(const common::ObCollationType cs_type, common::ObString &name, const bool check_for_path_char, const int64_t max_ident_len); diff --git a/src/sql/plan_cache/ob_plan_cache_value.cpp b/src/sql/plan_cache/ob_plan_cache_value.cpp index f5f8d2c342..ea7c2bb3c1 100644 --- a/src/sql/plan_cache/ob_plan_cache_value.cpp +++ b/src/sql/plan_cache/ob_plan_cache_value.cpp @@ -1925,7 +1925,8 @@ int ObPlanCacheValue::match_dep_schema(const ObPlanCacheCtx &pc_ctx, ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid null table schema", K(ret), K(i), K(schema_array.at(i)), K(stored_schema_objs_.at(i))); - } else if (schema_array.at(i).is_tmp_table_) { // check for tmp table + } else if (TMP_TABLE == schema_array.at(i).table_type_ + && schema_array.at(i).is_tmp_table_) { // check for mysql tmp table // 如果包含临时表 // 临时表也是同名表的一种特殊情况,但是这里用sessid_来区分了该pcv是否包含临时计划, // sessid_不为0,则是包含临时表的pocv,否则是普通表的pcv diff --git a/src/sql/resolver/ddl/ob_create_table_resolver.cpp b/src/sql/resolver/ddl/ob_create_table_resolver.cpp index f7ef0dde4f..ebb6a5bce1 100644 --- a/src/sql/resolver/ddl/ob_create_table_resolver.cpp +++ b/src/sql/resolver/ddl/ob_create_table_resolver.cpp @@ -56,6 +56,7 @@ ObCreateTableResolver::ObCreateTableResolver(ObResolverParams ¶ms) column_name_set_(), if_not_exist_(false), is_oracle_temp_table_(false), + is_temp_table_pk_added_(false), index_arg_(), current_index_name_set_(), cur_udt_set_id_(0) @@ -402,6 +403,7 @@ int ObCreateTableResolver::add_pk_key_for_oracle_temp_table(ObArray column_name_set_; bool if_not_exist_; bool is_oracle_temp_table_; //是否创建oracle的临时表 + bool is_temp_table_pk_added_; obrpc::ObCreateIndexArg index_arg_; IndexNameSet current_index_name_set_; diff --git a/src/sql/resolver/ddl/ob_truncate_table_resolver.cpp b/src/sql/resolver/ddl/ob_truncate_table_resolver.cpp index 91f7586211..0095d3c468 100644 --- a/src/sql/resolver/ddl/ob_truncate_table_resolver.cpp +++ b/src/sql/resolver/ddl/ob_truncate_table_resolver.cpp @@ -128,6 +128,7 @@ int ObTruncateTableResolver::resolve(const ParseNode &parser_tree) truncate_table_stmt->set_is_add_scheduler(is_add_to_scheduler); if (orig_table_schema->is_oracle_tmp_table()) { truncate_table_stmt->set_truncate_oracle_temp_table(); + truncate_table_stmt->set_oracle_temp_table_type(orig_table_schema->get_table_type()); } if (orig_table_schema->is_mysql_tmp_table()) { is_mysql_tmp_table = true; diff --git a/src/sql/resolver/ddl/ob_truncate_table_stmt.cpp b/src/sql/resolver/ddl/ob_truncate_table_stmt.cpp index 058447ceab..3def131864 100644 --- a/src/sql/resolver/ddl/ob_truncate_table_stmt.cpp +++ b/src/sql/resolver/ddl/ob_truncate_table_stmt.cpp @@ -22,13 +22,15 @@ namespace sql ObTruncateTableStmt::ObTruncateTableStmt(common::ObIAllocator *name_pool) : ObDDLStmt(name_pool, stmt::T_TRUNCATE_TABLE), - is_truncate_oracle_temp_table_(false) + is_truncate_oracle_temp_table_(false), + oracle_temp_table_type_(share::schema::MAX_TABLE_TYPE) { } ObTruncateTableStmt::ObTruncateTableStmt() : ObDDLStmt(stmt::T_TRUNCATE_TABLE), - is_truncate_oracle_temp_table_(false) + is_truncate_oracle_temp_table_(false), + oracle_temp_table_type_(share::schema::MAX_TABLE_TYPE) { } @@ -48,4 +50,3 @@ void ObTruncateTableStmt::set_table_name(const common::ObString &table_name) } //namespace sql } //namespace oceanbase - diff --git a/src/sql/resolver/ddl/ob_truncate_table_stmt.h b/src/sql/resolver/ddl/ob_truncate_table_stmt.h index af15d31748..71d5f9f9a8 100644 --- a/src/sql/resolver/ddl/ob_truncate_table_stmt.h +++ b/src/sql/resolver/ddl/ob_truncate_table_stmt.h @@ -42,10 +42,13 @@ public: virtual obrpc::ObDDLArg &get_ddl_arg() { return truncate_table_arg_; } void set_truncate_oracle_temp_table() { is_truncate_oracle_temp_table_ = true; } bool is_truncate_oracle_temp_table() { return is_truncate_oracle_temp_table_; } + void set_oracle_temp_table_type(share::schema::ObTableType oracle_temp_table_type) { oracle_temp_table_type_ = oracle_temp_table_type; } + share::schema::ObTableType get_oracle_temp_table_type() { return oracle_temp_table_type_; } TO_STRING_KV(K_(stmt_type),K_(truncate_table_arg)); private: obrpc::ObTruncateTableArg truncate_table_arg_; bool is_truncate_oracle_temp_table_; + share::schema::ObTableType oracle_temp_table_type_; DISALLOW_COPY_AND_ASSIGN(ObTruncateTableStmt); }; diff --git a/src/sql/resolver/dml/ob_del_upd_resolver.cpp b/src/sql/resolver/dml/ob_del_upd_resolver.cpp index d8e4c3ea82..7e8bcfb00c 100644 --- a/src/sql/resolver/dml/ob_del_upd_resolver.cpp +++ b/src/sql/resolver/dml/ob_del_upd_resolver.cpp @@ -3982,41 +3982,56 @@ int ObDelUpdResolver::add_new_sel_item_for_oracle_temp_table(ObSelectStmt &selec { int ret = OB_SUCCESS; if (is_oracle_tmp_table_) { - ObConstRawExpr *session_id_expr = NULL; + ObSysFunRawExpr *session_id_expr = NULL; + ObConstRawExpr *temp_table_type = NULL; ObConstRawExpr *sess_create_time_expr = NULL; - ObArray select_items; + ObSEArray select_items; SelectItem select_item; - if (OB_FAIL(params_.expr_factory_->create_raw_expr(T_INT, session_id_expr))) { + select_item.is_implicit_added_ = true; + + if (OB_FAIL(params_.expr_factory_->create_raw_expr(T_FUN_GET_TEMP_TABLE_SESSID, session_id_expr))) { LOG_WARN("create raw expr failed", K(ret)); } else if (OB_FAIL(params_.expr_factory_->create_raw_expr(T_INT, sess_create_time_expr))) { LOG_WARN("create raw expr failed", K(ret)); - } else if (OB_ISNULL(session_id_expr) || OB_ISNULL(sess_create_time_expr)) { + } else if (OB_FAIL(params_.expr_factory_->create_raw_expr(T_INT, temp_table_type))) { + LOG_WARN("create raw expr failed", K(ret)); + } else if (OB_ISNULL(session_id_expr) || OB_ISNULL(sess_create_time_expr) || OB_ISNULL(temp_table_type)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("dummy expr is null", K(session_id_expr), K(sess_create_time_expr)); - } else { + LOG_WARN("dummy expr is null", K(ret)); + } + if (OB_SUCC(ret)) { ObObj val; - val.set_int(session_info_->get_sessid_for_table()); - session_id_expr->set_value(val); - select_item.is_implicit_added_ = true; + val.set_int(oracle_tmp_table_type_); + temp_table_type->set_value(val); + } + if (OB_SUCC(ret)) { + session_id_expr->set_func_name(N_TEMP_TABLE_SSID); select_item.expr_ = session_id_expr; - if (OB_FAIL(select_items.push_back(select_item))) { + if (OB_FAIL(session_id_expr->add_param_expr(temp_table_type))) { + LOG_WARN("fail to add param expr", K(ret)); + } else if (OB_FAIL(session_id_expr->formalize(session_info_))) { + LOG_WARN("fail to formalize expr", K(ret)); + } else if (OB_FAIL(select_items.push_back(select_item))) { LOG_WARN("push subquery select items failed", K(ret)); - } else if (session_info_->is_obproxy_mode() && 0 == session_info_->get_sess_create_time()) { - ret = OB_NOT_SUPPORTED; - SQL_RESV_LOG(WARN, "can't insert into oracle temporary table via obproxy, upgrade obproxy first", K(ret)); - LOG_USER_ERROR(OB_NOT_SUPPORTED, "obproxy version is too old, insert into temporary table"); - } else { - val.set_int(session_info_->get_sess_create_time()); - sess_create_time_expr->set_value(val); - select_item.expr_ = sess_create_time_expr; - if (OB_FAIL(select_items.push_back(select_item))) { - LOG_WARN("push subquery select items failed", K(ret)); - } else if (OB_FAIL(add_select_items(select_stmt, select_items))) { - LOG_WARN("failed to add select items", K(ret)); - } - LOG_DEBUG("add __session_id & __sess_create_time to select item succeed"); } } + if (OB_SUCC(ret)) { + ObObj val; + val.set_int(0); + sess_create_time_expr->set_value(val); + select_item.expr_ = sess_create_time_expr; + if (OB_FAIL(sess_create_time_expr->formalize(session_info_))) { + LOG_WARN("fail to formalize expr", K(ret)); + } else if (OB_FAIL(select_items.push_back(select_item))) { + LOG_WARN("push subquery select items failed", K(ret)); + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(add_select_items(select_stmt, select_items))) { + LOG_WARN("failed to add select items", K(ret)); + } + } + LOG_DEBUG("add __session_id & __sess_create_time to select item succeed"); } return ret; } @@ -4090,36 +4105,41 @@ int ObDelUpdResolver::add_new_value_for_oracle_temp_table(ObIArray & { int ret = OB_SUCCESS; if (is_oracle_tmp_table_) { - ObConstRawExpr *session_id_expr = NULL; + ObSysFunRawExpr *session_id_expr = NULL; ObConstRawExpr *sess_create_time_expr = NULL; + ObConstRawExpr *temp_table_type = NULL; if (OB_ISNULL(session_info_)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid session_info_ or insert_stmt", K(session_info_)); - } else if (OB_FAIL(params_.expr_factory_->create_raw_expr(T_INT, session_id_expr))) { + LOG_WARN("invalid session_info_ ", K(session_info_)); + } else if (OB_FAIL(params_.expr_factory_->create_raw_expr(T_FUN_GET_TEMP_TABLE_SESSID, session_id_expr))) { LOG_WARN("create raw expr failed", K(ret)); } else if (OB_FAIL(params_.expr_factory_->create_raw_expr(T_INT, sess_create_time_expr))) { LOG_WARN("create raw expr failed", K(ret)); - } else if (OB_ISNULL(session_id_expr) || OB_ISNULL(sess_create_time_expr)) { + } else if (OB_FAIL(params_.expr_factory_->create_raw_expr(T_INT, temp_table_type))) { + LOG_WARN("create raw expr failed", K(ret)); + } else if (OB_ISNULL(session_id_expr) || OB_ISNULL(sess_create_time_expr) || OB_ISNULL(temp_table_type)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("dummy expr is null", K(session_id_expr), K(sess_create_time_expr)); } else { ObObj val; - val.set_int(session_info_->get_sessid_for_table()); - session_id_expr->set_value(val); - if (OB_FAIL(value_row.push_back(session_id_expr))) { + val.set_int(0); + sess_create_time_expr->set_value(val); + session_id_expr->set_func_name(N_TEMP_TABLE_SSID); + val.set_int(oracle_tmp_table_type_); + temp_table_type->set_value(val); + if (OB_FAIL(session_id_expr->add_param_expr(temp_table_type))) { + LOG_WARN("fail to add param expr", K(ret)); + } else if (OB_FAIL(session_id_expr->formalize(session_info_))) { + LOG_WARN("fail to formalize expr", K(ret)); + } else if (OB_FAIL(sess_create_time_expr->formalize(session_info_))) { + LOG_WARN("fail to formalize expr", K(ret)); + } else if (OB_FAIL(value_row.push_back(session_id_expr))) { + LOG_WARN("push back to output expr failed", K(ret)); + } else if (OB_FAIL(value_row.push_back(sess_create_time_expr))) { LOG_WARN("push back to output expr failed", K(ret)); - } else if (session_info_->is_obproxy_mode() && 0 == session_info_->get_sess_create_time()) { - ret = OB_NOT_SUPPORTED; - SQL_RESV_LOG(WARN, "can't insert into oracle temporary table via obproxy, upgrade obproxy first", K(ret)); - LOG_USER_ERROR(OB_NOT_SUPPORTED, "obproxy version is too old, insert into temporary table"); - } else { - val.set_int(session_info_->get_sess_create_time()); - sess_create_time_expr->set_value(val); - if (OB_FAIL(value_row.push_back(sess_create_time_expr))) { - LOG_WARN("push back to output expr failed", K(ret)); - } - LOG_DEBUG("add session id & sess create time value succeed", K(session_id_expr), K(sess_create_time_expr), K(value_row), K(lbt())); } + LOG_DEBUG("add session id & sess create time value succeed", + K(session_id_expr), K(sess_create_time_expr), K(value_row)); } } return ret; diff --git a/src/sql/resolver/dml/ob_del_upd_resolver.h b/src/sql/resolver/dml/ob_del_upd_resolver.h index 1daa46d54d..987c3a475f 100644 --- a/src/sql/resolver/dml/ob_del_upd_resolver.h +++ b/src/sql/resolver/dml/ob_del_upd_resolver.h @@ -230,6 +230,7 @@ protected: bool add_column = true); bool is_oracle_tmp_table() { return is_oracle_tmp_table_; } void set_is_oracle_tmp_table(bool is_temp_table) { is_oracle_tmp_table_ = is_temp_table; } + void set_oracle_tmp_table_type(int64_t type) { oracle_tmp_table_type_ = type; } int add_new_sel_item_for_oracle_temp_table(ObSelectStmt &select_stmt); int add_new_column_for_oracle_temp_table(uint64_t ref_table_id, uint64_t table_id = OB_INVALID_ID, ObDMLStmt *stmt = NULL); int add_new_value_for_oracle_temp_table(ObIArray &value_row); @@ -255,6 +256,7 @@ private: common::hash::ObPlacementHashSet insert_column_ids_; bool is_column_specify_; bool is_oracle_tmp_table_; //是否创建oracle的临时表 + int64_t oracle_tmp_table_type_; }; } /* namespace sql */ diff --git a/src/sql/resolver/dml/ob_insert_resolver.cpp b/src/sql/resolver/dml/ob_insert_resolver.cpp index 44fb0ad7b4..6807789fa6 100644 --- a/src/sql/resolver/dml/ob_insert_resolver.cpp +++ b/src/sql/resolver/dml/ob_insert_resolver.cpp @@ -443,6 +443,7 @@ int ObInsertResolver::resolve_insert_field(const ParseNode &insert_into, TableIt //oracle临时表各session不会创建自己的私有对象只能在数据增加时设置标记 session_info_->set_has_temp_table_flag(); set_is_oracle_tmp_table(true); + set_oracle_tmp_table_type(table_schema->is_oracle_sess_tmp_table() ? 0 : 1); } } } diff --git a/src/sql/resolver/expr/ob_raw_expr.cpp b/src/sql/resolver/expr/ob_raw_expr.cpp index 4a7f842c74..172eff5844 100644 --- a/src/sql/resolver/expr/ob_raw_expr.cpp +++ b/src/sql/resolver/expr/ob_raw_expr.cpp @@ -749,6 +749,7 @@ int ObRawExpr::is_const_inherit_expr(bool &is_const_inherit, || (T_FUN_SYS_LAST_INSERT_ID == type_ && get_param_count() > 0) || T_FUN_SYS_TO_BLOB == type_ || (T_FUN_SYS_SYSDATE == type_ && lib::is_mysql_mode()) + || T_FUN_GET_TEMP_TABLE_SESSID == type_ || (param_need_replace ? is_not_calculable_expr() : cnt_not_calculable_expr()) || (T_FUN_UDF == type_ && !static_cast(this)->is_deterministic())) { diff --git a/src/sql/rewrite/ob_transform_pre_process.cpp b/src/sql/rewrite/ob_transform_pre_process.cpp index 745c74433f..448d0c011a 100644 --- a/src/sql/rewrite/ob_transform_pre_process.cpp +++ b/src/sql/rewrite/ob_transform_pre_process.cpp @@ -120,15 +120,6 @@ int ObTransformPreProcess::transform_one_stmt(common::ObIArray LOG_TRACE("succeed to replace function", K(is_happened)); } } - if (OB_SUCC(ret)) { - if (OB_FAIL(transform_for_temporary_table(stmt, is_happened))) { - LOG_WARN("failed to transform for temporary table", K(ret)); - } else { - trans_happened |= is_happened; - OPT_TRACE("transform for temporary table:", is_happened); - LOG_TRACE("succeed to transform for temporary table", K(is_happened), K(ret)); - } - } if (OB_SUCC(ret)) { if (OB_FAIL(transform_for_rls_table(stmt, is_happened))) { LOG_WARN("failed to transform for rls table", K(ret)); @@ -146,6 +137,15 @@ int ObTransformPreProcess::transform_one_stmt(common::ObIArray LOG_TRACE("succeed to transform for merge into", K(is_happened), K(ret)); } } + if (OB_SUCC(ret)) { + if (OB_FAIL(transform_for_temporary_table(stmt, is_happened))) { + LOG_WARN("failed to transform for temporary table", K(ret)); + } else { + trans_happened |= is_happened; + OPT_TRACE("transform for temporary table:", is_happened); + LOG_TRACE("succeed to transform for temporary table", K(is_happened), K(ret)); + } + } if (OB_SUCC(ret)) { if (OB_FAIL(transform_outerjoin_exprs(stmt, is_happened))) { LOG_WARN("failed to transform outer join exprs", K(ret)); @@ -2994,7 +2994,7 @@ int ObTransformPreProcess::transform_for_temporary_table(ObDMLStmt *&stmt, ObSelectStmt *ref_query = NULL; TableItem *child_table = NULL; if (stmt->is_single_table_stmt()) { - if (OB_FAIL(add_filter_for_temporary_table(*stmt, *table_item))) { + if (OB_FAIL(add_filter_for_temporary_table(*stmt, *table_item, table_schema->is_oracle_trx_tmp_table()))) { LOG_WARN("add filter for temporary table failed", K(ret)); } else { trans_happened = true; @@ -3015,7 +3015,7 @@ int ObTransformPreProcess::transform_for_temporary_table(ObDMLStmt *&stmt, || OB_ISNULL(child_table = ref_query->get_table_item(0))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected view table", K(ret), K(*view_table)); - } else if (OB_FAIL(add_filter_for_temporary_table(*ref_query, *child_table))) { + } else if (OB_FAIL(add_filter_for_temporary_table(*ref_query, *child_table, table_schema->is_oracle_trx_tmp_table()))) { LOG_WARN("add filter for temporary table failed", K(ret)); } else { trans_happened = true; @@ -3050,26 +3050,22 @@ int ObTransformPreProcess::transform_for_temporary_table(ObDMLStmt *&stmt, //为stmt->where添加session_id = xxx int ObTransformPreProcess::add_filter_for_temporary_table(ObDMLStmt &stmt, - const TableItem &table_item) + const TableItem &table_item, + bool is_trans_scope_temp_table) { int ret = OB_SUCCESS; ObRawExpr *equal_expr = NULL; - ObConstRawExpr *expr_const = NULL; + ObConstRawExpr *temp_table_type = NULL; ObColumnRefRawExpr *expr_col = NULL; + ObSysFunRawExpr *expr_temp_table_ssid = NULL; if (OB_ISNULL(ctx_) || OB_ISNULL(ctx_->session_info_) || OB_ISNULL(ctx_->expr_factory_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("some parameter is NULL", K(ret), K(ctx_)); } - else if (OB_FAIL(ctx_->expr_factory_->create_raw_expr(T_UINT64, expr_const))) { - LOG_WARN("create const raw expr failed", K(ret)); - } else if (OB_ISNULL(expr_const)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("expr is null", K(expr_col), K(expr_const), K(ret)); - } else { - ObObj sid_obj; + + //build column expr + if (OB_SUCC(ret)) { ColumnItem *exist_col_item = NULL; - sid_obj.set_int(ctx_->session_info_->get_sessid_for_table()); - expr_const->set_value(sid_obj); if (NULL != (exist_col_item = stmt.get_column_item(table_item.table_id_, OB_HIDDEN_SESSION_ID_COLUMN_NAME))) { expr_col = exist_col_item->expr_; } else { @@ -3086,7 +3082,7 @@ int ObTransformPreProcess::add_filter_for_temporary_table(ObDMLStmt &stmt, expr_col->set_column_name(OB_HIDDEN_SESSION_ID_COLUMN_NAME); expr_col->set_ref_id(table_item.table_id_, OB_HIDDEN_SESSION_ID_COLUMN_ID); expr_col->set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); - expr_col->set_collation_level(CS_LEVEL_SYSCONST); + expr_col->set_collation_level(CS_LEVEL_IMPLICIT); expr_col->set_result_type(result_type); column_item.expr_ = expr_col; column_item.table_id_ = expr_col->get_table_id(); @@ -3099,16 +3095,51 @@ int ObTransformPreProcess::add_filter_for_temporary_table(ObDMLStmt &stmt, } } } - if (OB_FAIL(ret)) { - //do nothing - } else if (OB_FAIL(ObRawExprUtils::create_equal_expr(*(ctx_->expr_factory_), - ctx_->session_info_, - expr_const, - expr_col, - equal_expr))) { + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(ctx_->expr_factory_->create_raw_expr(T_INT, temp_table_type))) { + LOG_WARN("create const raw expr failed", K(ret)); + } else if (OB_ISNULL(temp_table_type)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expr temp table ssid", K(ret)); + } else { + ObObj val; + val.set_int(is_trans_scope_temp_table ? 1 : 0); + temp_table_type->set_value(val); + } + } + + //build session id expr + if (OB_SUCC(ret)) { + if (OB_FAIL(ctx_->expr_factory_->create_raw_expr(T_FUN_GET_TEMP_TABLE_SESSID, expr_temp_table_ssid))) { + LOG_WARN("create const raw expr failed", K(ret)); + } else if (OB_ISNULL(expr_temp_table_ssid)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expr temp table ssid", K(ret)); + } else { + expr_temp_table_ssid->set_func_name(N_TEMP_TABLE_SSID); + if (OB_FAIL(expr_temp_table_ssid->add_param_expr(temp_table_type))) { + LOG_WARN("fail to add param expr", K(ret)); + } + } + } + + //build equal expr + if (OB_SUCC(ret)) { + if (OB_FAIL(ObRawExprUtils::create_equal_expr(*(ctx_->expr_factory_), + ctx_->session_info_, + expr_temp_table_ssid, + expr_col, + equal_expr))) { LOG_WARN("Creation of equal expr for outer stmt fails", K(ret)); } - if (OB_FAIL(stmt.get_condition_exprs().push_back(equal_expr))) { + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(equal_expr->formalize(ctx_->session_info_))) { + LOG_WARN("fail to formalize expr", K(ret)); + } else if (OB_FAIL(stmt.get_condition_exprs().push_back(equal_expr))) { LOG_WARN("failed to push back new filter", K(ret)); } else { LOG_TRACE("add new filter succeed", K(stmt.get_condition_exprs()), K(*equal_expr)); diff --git a/src/sql/rewrite/ob_transform_pre_process.h b/src/sql/rewrite/ob_transform_pre_process.h index a990dcc3d6..e369c5f73c 100644 --- a/src/sql/rewrite/ob_transform_pre_process.h +++ b/src/sql/rewrite/ob_transform_pre_process.h @@ -282,7 +282,8 @@ struct DistinctObjMeta */ int transform_for_temporary_table(ObDMLStmt *&stmt, bool &trans_happened); int add_filter_for_temporary_table(ObDMLStmt &stmt, - const TableItem &table_item); + const TableItem &table_item, + bool is_trans_scope_temp_table); int collect_all_tableitem(ObDMLStmt *stmt, TableItem *table_item, common::ObArray &table_item_list); diff --git a/src/sql/session/ob_sql_session_info.cpp b/src/sql/session/ob_sql_session_info.cpp index 50c927179a..3747351ff8 100644 --- a/src/sql/session/ob_sql_session_info.cpp +++ b/src/sql/session/ob_sql_session_info.cpp @@ -181,7 +181,8 @@ ObSQLSessionInfo::ObSQLSessionInfo(const uint64_t tenant_id) : dblink_context_(this), sql_req_level_(0), expect_group_id_(OB_INVALID_ID), - group_id_not_expected_(false) + gtt_session_scope_unique_id_(0), + gtt_trans_scope_unique_id_(0) { MEMSET(tenant_buff_, 0, sizeof(share::ObTenantSpaceFetcher)); } @@ -342,6 +343,10 @@ void ObSQLSessionInfo::reset(bool skip_sys_var) ObBasicSessionInfo::reset(skip_sys_var); txn_free_route_ctx_.reset(); } + gtt_session_scope_unique_id_ = 0; + gtt_trans_scope_unique_id_ = 0; + gtt_session_scope_ids_.reset(); + gtt_trans_scope_ids_.reset(); } void ObSQLSessionInfo::clean_status() @@ -589,10 +594,13 @@ int ObSQLSessionInfo::delete_from_oracle_temp_tables(const obrpc::ObDropTableArg common::ObOracleSqlProxy oracle_sql_proxy; ObSchemaGetterGuard schema_guard; const ObDatabaseSchema *database_schema = NULL; - ObSEArray table_schemas; + //ObSEArray table_schemas; obrpc::ObDropTableArg &drop_table_arg = const_cast(const_drop_table_arg); const share::schema::ObTableType table_type = drop_table_arg.table_type_; const uint64_t tenant_id = drop_table_arg.tenant_id_; + const ObTableSchema *table_schema = NULL; + user_sql_proxy = &oracle_sql_proxy; + if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard( tenant_id, schema_guard))) { @@ -602,15 +610,17 @@ int ObSQLSessionInfo::delete_from_oracle_temp_tables(const obrpc::ObDropTableArg LOG_WARN("sql proxy is null", K(ret)); } else if (OB_FAIL(oracle_sql_proxy.init(sql_proxy->get_pool()))) { LOG_WARN("init oracle sql proxy failed", K(ret)); - } else if (OB_FAIL(schema_guard.get_table_schemas_in_tenant(tenant_id, table_schemas))) { - LOG_WARN("fail to get table schema", K(ret), K(tenant_id)); - } else { - user_sql_proxy = &oracle_sql_proxy; - for (int64_t i = 0; i < table_schemas.count() && OB_SUCC(ret); i++) { - const ObSimpleTableSchemaV2 *table_schema = table_schemas.at(i); - if (OB_ISNULL(table_schema)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("got invalid schema", K(ret), K(i)); + } else if (TMP_TABLE_ORA_SESS == table_type || TMP_TABLE_ORA_TRX == table_type) { + ObIArray &table_ids = table_type == share::schema::TMP_TABLE_ORA_TRX ? + get_gtt_trans_scope_ids() : get_gtt_session_scope_ids(); + uint64_t unique_id = table_type == share::schema::TMP_TABLE_ORA_TRX ? + get_gtt_trans_scope_unique_id() : get_gtt_session_scope_unique_id(); + LOG_DEBUG("delete temp table", K(table_ids), K(unique_id)); + for (int64_t i = 0; OB_SUCC(ret) && i < table_ids.count(); i++) { + if (OB_FAIL(schema_guard.get_table_schema(tenant_id, table_ids.at(i), table_schema))) { + LOG_WARN("fail to get table schema", K(ret)); + } else if (OB_ISNULL(table_schema)) { + //table may be dropped, ignore } else if (tenant_id != table_schema->get_tenant_id()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tenant_id not match", K(ret), K(tenant_id), "table_id", table_schema->get_table_id()); @@ -628,28 +638,18 @@ int ObSQLSessionInfo::delete_from_oracle_temp_tables(const obrpc::ObDropTableArg LOG_DEBUG("skip table schema in recyclebin", K(*table_schema)); } else { const int64_t limit = 1000; - if (0 == drop_table_arg.sess_create_time_) { - ret = sql.assign_fmt("DELETE FROM \"%.*s\".\"%.*s\" WHERE %s = %ld AND ROWNUM <= %ld", - database_schema->get_database_name_str().length(), - database_schema->get_database_name_str().ptr(), - table_schema->get_table_name_str().length(), - table_schema->get_table_name_str().ptr(), - OB_HIDDEN_SESSION_ID_COLUMN_NAME, drop_table_arg.session_id_, - limit); - } else { - ret = sql.assign_fmt("DELETE FROM \"%.*s\".\"%.*s\" WHERE %s = %ld AND %s <> %ld AND ROWNUM <= %ld", - database_schema->get_database_name_str().length(), - database_schema->get_database_name_str().ptr(), - table_schema->get_table_name_str().length(), - table_schema->get_table_name_str().ptr(), - OB_HIDDEN_SESSION_ID_COLUMN_NAME, drop_table_arg.session_id_, - OB_HIDDEN_SESS_CREATE_TIME_COLUMN_NAME, drop_table_arg.sess_create_time_, - limit); - } + ret = sql.assign_fmt("DELETE FROM \"%.*s\".\"%.*s\" WHERE %s = %ld AND ROWNUM <= %ld", + database_schema->get_database_name_str().length(), + database_schema->get_database_name_str().ptr(), + table_schema->get_table_name_str().length(), + table_schema->get_table_name_str().ptr(), + OB_HIDDEN_SESSION_ID_COLUMN_NAME, unique_id, + limit); if (OB_SUCC(ret)) { int64_t affect_rows = 0; int64_t last_batch_affect_rows = limit; + int64_t cur_time = ObTimeUtility::current_time(); int64_t cur_timeout_backup = THIS_WORKER.get_timeout_ts(); THIS_WORKER.set_timeout_ts(ObTimeUtility::current_time() + OB_MAX_USER_SPECIFIED_TIMEOUT); while (OB_SUCC(ret) && last_batch_affect_rows > 0) { @@ -669,11 +669,18 @@ int ObSQLSessionInfo::delete_from_oracle_temp_tables(const obrpc::ObDropTableArg } else { LOG_WARN("failed to delete rows in oracle temporary table", K(ret), K(sql)); } + LOG_INFO("delete rows in oracle temporary table", K(sql), K(affect_rows), + "clean_time", ObTimeUtility::current_time() - cur_time); THIS_WORKER.set_timeout_ts(cur_timeout_backup); } } } } + + if (TMP_TABLE_ORA_TRX == table_type && !get_is_deserialized()) { + gtt_trans_scope_ids_.reuse(); + gen_gtt_trans_scope_unique_id(); + } } return ret; } @@ -1523,7 +1530,11 @@ OB_DEF_SERIALIZE(ObSQLSessionInfo) proxy_version_, min_proxy_version_ps_, thread_data_.is_in_retry_, - ddl_info_); + ddl_info_, + gtt_session_scope_unique_id_, + gtt_trans_scope_unique_id_, + gtt_session_scope_ids_, + gtt_trans_scope_ids_); return ret; } @@ -1550,7 +1561,11 @@ OB_DEF_DESERIALIZE(ObSQLSessionInfo) proxy_version_, min_proxy_version_ps_, thread_data_.is_in_retry_, - ddl_info_); + ddl_info_, + gtt_session_scope_unique_id_, + gtt_trans_scope_unique_id_, + gtt_session_scope_ids_, + gtt_trans_scope_ids_); (void)ObSQLUtils::adjust_time_by_ntp_offset(thread_data_.cur_query_start_time_); return ret; } @@ -1578,7 +1593,11 @@ OB_DEF_SERIALIZE_SIZE(ObSQLSessionInfo) proxy_version_, min_proxy_version_ps_, thread_data_.is_in_retry_, - ddl_info_); + ddl_info_, + gtt_session_scope_unique_id_, + gtt_trans_scope_unique_id_, + gtt_session_scope_ids_, + gtt_trans_scope_ids_); return len; } @@ -3055,6 +3074,22 @@ int ObSysVarEncoder::display_sess_info(ObSQLSessionInfo &sess, const char* curre return ret; } +void ObSQLSessionInfo::gen_gtt_session_scope_unique_id() +{ + static int64_t cur_ts = 0; + int64_t next_ts = ObSQLUtils::combine_server_id(ObSQLUtils::get_next_ts(cur_ts), GCTX.server_id_); + gtt_session_scope_unique_id_ = next_ts; + LOG_DEBUG("check temporary table ssid session scope", K(next_ts), K(get_sessid_for_table()), K(GCTX.server_id_), K(lbt())); +} + +void ObSQLSessionInfo::gen_gtt_trans_scope_unique_id() +{ + static int64_t cur_ts = 0; + int64_t next_ts = ObSQLUtils::combine_server_id(ObSQLUtils::get_next_ts(cur_ts), GCTX.server_id_); + gtt_trans_scope_unique_id_ = next_ts; + LOG_DEBUG("check temporary table ssid trans scope", K(next_ts), K(get_sessid_for_table()), K(GCTX.server_id_), K(lbt())); +} + int ObAppInfoEncoder::serialize(ObSQLSessionInfo &sess, char *buf, const int64_t length, int64_t &pos) { int ret = OB_SUCCESS; diff --git a/src/sql/session/ob_sql_session_info.h b/src/sql/session/ob_sql_session_info.h index 9a52a47b74..bcd04b5244 100644 --- a/src/sql/session/ob_sql_session_info.h +++ b/src/sql/session/ob_sql_session_info.h @@ -780,6 +780,14 @@ public: int drop_reused_oracle_temp_tables(); int delete_from_oracle_temp_tables(const obrpc::ObDropTableArg &const_drop_table_arg); + //To generate an unique key for Oracle Global Temporary Table + int64_t get_gtt_session_scope_unique_id() const { return gtt_session_scope_unique_id_; } + int64_t get_gtt_trans_scope_unique_id() const { return gtt_trans_scope_unique_id_; } + void gen_gtt_session_scope_unique_id(); + void gen_gtt_trans_scope_unique_id(); + common::ObIArray &get_gtt_session_scope_ids() { return gtt_session_scope_ids_; } + common::ObIArray &get_gtt_trans_scope_ids() { return gtt_trans_scope_ids_; } + void set_for_trigger_package(bool value) { is_for_trigger_package_ = value; } bool is_for_trigger_package() const { return is_for_trigger_package_; } void set_trans_type(transaction::ObTxClass t) { trans_type_ = t; } @@ -1397,6 +1405,13 @@ private: // This situation is unexpected and will report a warning to user. bool group_id_not_expected_; ObOptimizerTraceImpl optimizer_tracer_; + //For Oracle Global Temporary Table + //unique key: obs_id(16bit) + timestamp(48bit) + int64_t gtt_session_scope_unique_id_; + int64_t gtt_trans_scope_unique_id_; + //storing table ids of accessed gtts in the session + common::ObSEArray gtt_session_scope_ids_; + common::ObSEArray gtt_trans_scope_ids_; }; inline bool ObSQLSessionInfo::is_terminate(int &ret) const