Fix temp table related bugs

This commit is contained in:
xianyu-w
2023-08-04 10:18:34 +00:00
committed by ob-robot
parent 558f74a2d6
commit 88430a9d96
30 changed files with 2750 additions and 1064 deletions

View File

@ -68,12 +68,23 @@ int ObTransformPreProcess::transform_one_stmt(common::ObIArray<ObParentDMLStmt>
OB_FAIL(formalize_limit_expr(*stmt))) {
LOG_WARN("formalize stmt fialed", K(ret));
} else {
if (OB_FAIL(transform_udt_columns(parent_stmts, stmt, is_happened))) {
LOG_WARN("failed to transform for transform for cast multiset", K(ret));
} else {
trans_happened |= is_happened;
OPT_TRACE("transform for udt columns", is_happened);
LOG_TRACE("succeed to transform for udt columns", K(is_happened), K(ret));
if (OB_SUCC(ret) && parent_stmts.empty()) {
if (OB_FAIL(expand_correlated_cte(stmt, is_happened))) {
LOG_WARN("failed to expand correlated cte", K(ret));
} else {
trans_happened |= is_happened;
OPT_TRACE("expand correlated cte", is_happened);
LOG_TRACE("succeed to expand correlated cte", K(is_happened), K(ret));
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(transform_udt_columns(parent_stmts, stmt, is_happened))) {
LOG_WARN("failed to transform for transform for cast multiset", K(ret));
} else {
trans_happened |= is_happened;
OPT_TRACE("transform for udt columns", is_happened);
LOG_TRACE("succeed to transform for udt columns", K(is_happened), K(ret));
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(transform_cast_multiset_for_stmt(stmt, is_happened))) {
@ -9451,5 +9462,134 @@ int ObTransformPreProcess::remove_last_insert_id(ObRawExpr *&expr) {
return ret;
}
int ObTransformPreProcess::expand_correlated_cte(ObDMLStmt *stmt, bool& trans_happened)
{
int ret = OB_SUCCESS;
ObSEArray<ObDMLStmt::TempTableInfo, 8> temp_table_infos;
if (OB_ISNULL(stmt)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("stmt is NULL", K(ret));
} else if (OB_FAIL(stmt->collect_temp_table_infos(temp_table_infos))) {
LOG_WARN("failed to collect temp table infos", K(ret));
}
for (int64_t i = 0; OB_SUCC(ret) && i < temp_table_infos.count(); i ++) {
bool is_correlated = false;
ObSEArray<ObSelectStmt *, 4> 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::expand_temp_table(ctx_, temp_table_infos.at(i)))) {
LOG_WARN("failed to extend temp table", K(ret));
} else {
trans_happened = true;
}
}
return ret;
}
int ObTransformPreProcess::check_exec_param_correlated(const ObRawExpr *expr, bool &is_correlated)
{
int ret = OB_SUCCESS;
is_correlated = false;
if (OB_ISNULL(expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("expr is null", K(ret), K(expr));
} else if (expr->is_exec_param_expr()) {
if (!expr->has_flag(BE_USED)) {
is_correlated = true;
}
} else if (expr->has_flag(CNT_DYNAMIC_PARAM)) {
for (int64_t i = 0; OB_SUCC(ret) && !is_correlated && i < expr->get_param_count(); ++i) {
if (OB_FAIL(SMART_CALL(check_exec_param_correlated(expr->get_param_expr(i),
is_correlated)))) {
LOG_WARN("failed to check exec param correlated", K(ret));
}
}
}
return ret;
}
int ObTransformPreProcess::check_is_correlated_cte(ObSelectStmt *stmt, ObIArray<ObSelectStmt *> &visited_cte, bool &is_correlated)
{
int ret = OB_SUCCESS;
ObArray<ObSelectStmt *> child_stmts;
ObArray<ObRawExpr *> relation_exprs;
is_correlated = false;
if (OB_ISNULL(stmt)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("stmt is NULL", K(ret));
} else if (OB_FAIL(stmt->get_relation_exprs(relation_exprs))) {
LOG_WARN("failed to get relation exprs", K(ret));
} else 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_correlated && i < relation_exprs.count(); ++i) {
ObRawExpr *expr = relation_exprs.at(i);
if (OB_FAIL(check_exec_param_correlated(expr, is_correlated))) {
LOG_WARN("failed to check exec param level", K(ret));
}
}
if (!is_correlated) {
// add flag to mark the exec param refer the same table
for (int64_t i = 0; OB_SUCC(ret) && i < stmt->get_subquery_expr_size(); ++i) {
ObQueryRefRawExpr *query_ref = stmt->get_subquery_exprs().at(i);
if (OB_ISNULL(query_ref)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("query ref is null", K(ret), K(query_ref));
}
for (int64_t j = 0; OB_SUCC(ret) && j < query_ref->get_exec_params().count(); ++j) {
ObRawExpr *exec_param = query_ref->get_exec_params().at(j);
if (OB_ISNULL(exec_param)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("exec param is null", K(ret));
} else if (OB_FAIL(exec_param->add_flag(BE_USED))) {
LOG_WARN("failed to add flag", K(ret));
}
}
}
for (int64_t i = 0; OB_SUCC(ret) && !is_correlated && i < child_stmts.count(); ++i) {
if (OB_FAIL(SMART_CALL(check_is_correlated_cte(child_stmts.at(i), visited_cte, is_correlated)))) {
LOG_WARN("failed to get non correlated subquery", K(ret));
}
}
for (int64_t i = 0; OB_SUCC(ret) && i < stmt->get_table_size(); ++i) {
TableItem *table = stmt->get_table_item(i);
if (OB_ISNULL(table)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null table item", K(ret));
} else if (!table->is_temp_table()) {
//do nothing
} else if (ObOptimizerUtil::find_item(visited_cte, table->ref_query_)) {
//do nothing
} else if (OB_FAIL(visited_cte.push_back(table->ref_query_))) {
LOG_WARN("failed to push back stmt", K(ret));
} else if (OB_FAIL(SMART_CALL(check_is_correlated_cte(table->ref_query_, visited_cte, is_correlated)))) {
LOG_WARN("failed to get non correlated subquery", K(ret));
}
}
// clear flag
for (int64_t i = 0; OB_SUCC(ret) && i < stmt->get_subquery_expr_size(); ++i) {
ObQueryRefRawExpr *query_ref = stmt->get_subquery_exprs().at(i);
if (OB_ISNULL(query_ref)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("query ref is null", K(ret), K(query_ref));
}
for (int64_t j = 0; OB_SUCC(ret) && j < query_ref->get_exec_params().count(); ++j) {
ObRawExpr *exec_param = query_ref->get_exec_params().at(j);
if (OB_ISNULL(exec_param)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("exec param is null", K(ret));
} else {
exec_param->clear_flag(BE_USED);
}
}
}
}
return ret;
}
} // end namespace sql
} // end namespace oceanbase