From 62d96c8fa44613b376289f77989773c98433bfa9 Mon Sep 17 00:00:00 2001 From: xianyu-w <707512433@qq.com> Date: Fri, 9 Feb 2024 19:25:38 +0000 Subject: [PATCH] Fix temp table bugs --- src/sql/rewrite/ob_stmt_comparer.cpp | 2 ++ src/sql/rewrite/ob_transform_dblink.cpp | 4 ++- src/sql/rewrite/ob_transform_pre_process.cpp | 7 ++++ src/sql/rewrite/ob_transform_temp_table.cpp | 6 ++++ src/sql/rewrite/ob_transform_utils.cpp | 35 ++++++++++++++++++++ src/sql/rewrite/ob_transform_utils.h | 2 ++ 6 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/sql/rewrite/ob_stmt_comparer.cpp b/src/sql/rewrite/ob_stmt_comparer.cpp index eaf047c7bf..427fbd4a19 100644 --- a/src/sql/rewrite/ob_stmt_comparer.cpp +++ b/src/sql/rewrite/ob_stmt_comparer.cpp @@ -1196,6 +1196,8 @@ int ObStmtComparer::compare_table_item(const ObDMLStmt *first, } else if (map_info.view_select_item_map_.count() < first->get_table_size() && OB_FAIL(map_info.view_select_item_map_.prepare_allocate(first->get_table_size()))) { LOG_WARN("failed to pre-allocate generated table map", K(ret)); + } else if (first_table->for_update_ || second_table->for_update_) { + relation = QueryRelation::QUERY_UNCOMPARABLE; } else if (first_table->is_temp_table() && second_table->is_temp_table()) { if (first_table->ref_query_ == second_table->ref_query_) { relation = QueryRelation::QUERY_EQUAL; diff --git a/src/sql/rewrite/ob_transform_dblink.cpp b/src/sql/rewrite/ob_transform_dblink.cpp index 7789ed212c..364e521b51 100644 --- a/src/sql/rewrite/ob_transform_dblink.cpp +++ b/src/sql/rewrite/ob_transform_dblink.cpp @@ -750,7 +750,9 @@ int ObTransformDBlink::check_is_link_table(TableItem *table, is_link_table = true; dblink_id = table->dblink_id_; is_reverse_link = table->is_reverse_link_; - } else if (table->is_generated_table() || table->is_temp_table()) { + } else if (table->is_temp_table()) { + is_link_table = false; + } else if (table->is_generated_table()) { if (OB_ISNULL(table->ref_query_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpect null ref query", K(ret)); diff --git a/src/sql/rewrite/ob_transform_pre_process.cpp b/src/sql/rewrite/ob_transform_pre_process.cpp index 9db038e1e6..ed77f1a343 100644 --- a/src/sql/rewrite/ob_transform_pre_process.cpp +++ b/src/sql/rewrite/ob_transform_pre_process.cpp @@ -10239,11 +10239,18 @@ int ObTransformPreProcess::expand_correlated_cte(ObDMLStmt *stmt, bool& trans_ha } for (int64_t i = 0; OB_SUCC(ret) && i < temp_table_infos.count(); i ++) { bool is_correlated = false; + bool can_expand = true; ObSEArray dummy; if (OB_FAIL(check_is_correlated_cte(temp_table_infos.at(i).temp_table_query_, dummy, is_correlated))) { LOG_WARN("failed to check is correlated cte", K(ret)); } else if (!is_correlated) { //do nothing + } else if (OB_FAIL(ObTransformUtils::check_expand_temp_table_valid(temp_table_infos.at(i).temp_table_query_, can_expand))) { + LOG_WARN("failed to check expand temp table valid", K(ret)); + } else if (!can_expand) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("Correlated CTE Not Supported", K(ret)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "Correlated CTE"); } else if (OB_FAIL(ObTransformUtils::expand_temp_table(ctx_, temp_table_infos.at(i)))) { LOG_WARN("failed to extend temp table", K(ret)); } else { diff --git a/src/sql/rewrite/ob_transform_temp_table.cpp b/src/sql/rewrite/ob_transform_temp_table.cpp index 42c176fe93..b919e1cdf2 100644 --- a/src/sql/rewrite/ob_transform_temp_table.cpp +++ b/src/sql/rewrite/ob_transform_temp_table.cpp @@ -210,12 +210,18 @@ int ObTransformTempTable::expand_temp_table(ObIArray &temp_table_ bool is_oversize_stmt = false; int64_t stmt_size = 0; bool need_expand = false; + bool can_expand = true; OPT_TRACE("try to expand temp table:", helper.temp_table_query_); if (OB_ISNULL(helper.temp_table_query_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpect null ref query", K(helper), K(ret)); } else if (OB_FAIL(check_stmt_size(helper.temp_table_query_, stmt_size, is_oversize_stmt))) { LOG_WARN("check stmt size failed", K(ret)); + } else if (OB_FAIL(ObTransformUtils::check_expand_temp_table_valid(helper.temp_table_query_, can_expand))) { + LOG_WARN("failed to check expand temp table valid", K(ret)); + } else if (!can_expand) { + // do nothing + OPT_TRACE("CTE can not be expanded"); } else if (OB_FAIL(check_hint_allowed_trans(*helper.temp_table_query_, force_inline, force_materia))) { diff --git a/src/sql/rewrite/ob_transform_utils.cpp b/src/sql/rewrite/ob_transform_utils.cpp index 8fc2c9115b..4781a0acfb 100644 --- a/src/sql/rewrite/ob_transform_utils.cpp +++ b/src/sql/rewrite/ob_transform_utils.cpp @@ -14245,6 +14245,41 @@ int ObTransformUtils::get_stmt_map_after_copy(ObDMLStmt *origin_stmt, return ret; } +int ObTransformUtils::check_expand_temp_table_valid(ObSelectStmt *stmt, bool &is_valid) +{ + int ret = OB_SUCCESS; + ObSEArray exprs; + is_valid = true; + if (OB_ISNULL(stmt)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null stmt", K(ret)); + } else if (OB_FAIL(stmt->get_relation_exprs(exprs))) { + LOG_WARN("failed to get relation exprs", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && is_valid && i < exprs.count(); i++) { + if (OB_ISNULL(exprs.at(i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected null", K(ret)); + } else if (exprs.at(i)->has_flag(CNT_RAND_FUNC) || + exprs.at(i)->has_flag(CNT_STATE_FUNC) || + exprs.at(i)->has_flag(CNT_DYNAMIC_USER_VARIABLE)) { + is_valid = false; + } + } + if (OB_SUCC(ret) && is_valid) { + ObSEArray child_stmts; + if (OB_FAIL(stmt->get_child_stmts(child_stmts))) { + LOG_WARN("failed to get child stmts", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && is_valid && i < child_stmts.count(); i++) { + if (OB_FAIL(SMART_CALL(check_expand_temp_table_valid(child_stmts.at(i), is_valid)))) { + LOG_WARN("failed to check expand temp table valid", K(ret)); + } + } + } + return ret; +} + int ObTransformUtils::expand_temp_table(ObTransformerCtx *ctx, ObDMLStmt::TempTableInfo& table_info) { int ret = OB_SUCCESS; diff --git a/src/sql/rewrite/ob_transform_utils.h b/src/sql/rewrite/ob_transform_utils.h index 92e3d3eedf..44d9189998 100644 --- a/src/sql/rewrite/ob_transform_utils.h +++ b/src/sql/rewrite/ob_transform_utils.h @@ -1820,6 +1820,8 @@ public: const ObIArray &group_exprs, bool &bret); + static int check_expand_temp_table_valid(ObSelectStmt *stmt, bool &is_valid); + static int expand_temp_table(ObTransformerCtx *ctx, ObDMLStmt::TempTableInfo& table_info); static int get_stmt_map_after_copy(ObDMLStmt *origin_stmt,