Fix dblink bugs

This commit is contained in:
xianyu-w
2023-06-07 09:23:50 +00:00
committed by ob-robot
parent d44134ee44
commit 7e1f2919c5
3 changed files with 128 additions and 6 deletions

View File

@ -101,7 +101,8 @@ int ObRawExprPrinter::print(ObRawExpr *expr)
&& scope_ != T_FIELD_LIST_SCOPE && scope_ != T_FIELD_LIST_SCOPE
&& scope_ != T_GROUP_SCOPE && scope_ != T_GROUP_SCOPE
&& scope_ != T_WHERE_SCOPE && scope_ != T_WHERE_SCOPE
&& scope_ != T_NONE_SCOPE) { && scope_ != T_NONE_SCOPE
&& scope_ != T_ORDER_SCOPE) {
//expr is a alias column ref //expr is a alias column ref
//alias column target list //alias column target list
PRINT_QUOT; PRINT_QUOT;
@ -803,7 +804,21 @@ int ObRawExprPrinter::print(ObOpRawExpr *expr)
SET_SYMBOL_IF_EMPTY("MULTISET"); SET_SYMBOL_IF_EMPTY("MULTISET");
break; break;
} }
case T_OP_BOOL: case T_OP_BOOL:{
CK(1 == expr->get_param_count());
if (print_params_.for_dblink_) {
DATA_PRINTF("(case when (");
PRINT_EXPR(expr->get_param_expr(0));
DATA_PRINTF(") then 1 else 0 end)");
} else if (expr->has_flag(IS_INNER_ADDED_EXPR)) {
// ignore print inner added expr
PRINT_EXPR(expr->get_param_expr(0));
} else {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("bool expr have to be inner expr for now", K(ret), K(*expr));
}
break;
}
case T_FUN_SYS_REMOVE_CONST: { case T_FUN_SYS_REMOVE_CONST: {
if (expr->has_flag(IS_INNER_ADDED_EXPR)) { if (expr->has_flag(IS_INNER_ADDED_EXPR)) {
// ignore print inner added expr // ignore print inner added expr

View File

@ -482,10 +482,12 @@ int ObTransformDBlink::collect_link_table(ObDMLStmt *stmt,
all_table_from_one_dblink = true; all_table_from_one_dblink = true;
bool has_special_expr = false; bool has_special_expr = false;
is_reverse_link = false; is_reverse_link = false;
ObSelectStmt *sel_stmt = static_cast<ObSelectStmt *>(stmt);
if (OB_ISNULL(stmt)) { if (OB_ISNULL(stmt)) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null stmt", K(ret)); LOG_WARN("unexpect null stmt", K(ret));
} else if (stmt->has_sequence() || stmt->is_hierarchical_query() || stmt->is_unpivot_select()) { } else if (stmt->has_sequence() || stmt->is_hierarchical_query() || stmt->is_unpivot_select() ||
(stmt->is_select_stmt() && sel_stmt->has_select_into())) {
all_table_from_one_dblink = false; all_table_from_one_dblink = false;
} else if (has_invalid_link_expr(*stmt, has_special_expr)) { } else if (has_invalid_link_expr(*stmt, has_special_expr)) {
LOG_WARN("failed to check stmt has invalid link expr", K(ret)); LOG_WARN("failed to check stmt has invalid link expr", K(ret));
@ -919,7 +921,9 @@ int ObTransformDBlink::split_link_table_info(ObDMLStmt *stmt, ObIArray<LinkTable
} }
//remove table item which is generate link table //remove table item which is generate link table
for (int64_t i = 0; OB_SUCC(ret) && i < temp_helpers.count(); ++i) { for (int64_t i = 0; OB_SUCC(ret) && i < temp_helpers.count(); ++i) {
if (temp_helpers.at(i).table_items_.count() != 1) { if (!(temp_helpers.at(i).table_items_.count() == 1 &&
temp_helpers.at(i).semi_infos_.empty() &&
temp_helpers.at(i).conditions_.empty())) {
if (OB_FAIL(new_helpers.push_back(temp_helpers.at(i)))) { if (OB_FAIL(new_helpers.push_back(temp_helpers.at(i)))) {
LOG_WARN("failed to add helper", K(ret)); LOG_WARN("failed to add helper", K(ret));
} }
@ -1001,6 +1005,7 @@ int ObTransformDBlink::inner_split_link_table_info(ObDMLStmt *stmt,
temp.dblink_id_ = helper.dblink_id_; temp.dblink_id_ = helper.dblink_id_;
temp.is_reverse_link_ = helper.is_reverse_link_; temp.is_reverse_link_ = helper.is_reverse_link_;
temp.parent_table_ = helper.parent_table_; temp.parent_table_ = helper.parent_table_;
temp.parent_semi_info_ = helper.parent_semi_info_;
if (OB_FAIL(temp.table_items_.push_back(table))) { if (OB_FAIL(temp.table_items_.push_back(table))) {
LOG_WARN("failed to push back table item", K(ret)); LOG_WARN("failed to push back table item", K(ret));
} else if (OB_FAIL(temp_helpers.push_back(temp))) { } else if (OB_FAIL(temp_helpers.push_back(temp))) {
@ -1028,6 +1033,47 @@ int ObTransformDBlink::inner_split_link_table_info(ObDMLStmt *stmt,
} }
} }
} }
//redistribute semi infos
for (int64_t i = 0; OB_SUCC(ret) && i < helper.semi_infos_.count(); ++i) {
SemiInfo *semi_info = helper.semi_infos_.at(i);
ObRelIds semi_tables;
if (OB_ISNULL(semi_info)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null semi info", K(ret));
} else if (OB_FAIL(ObTransformUtils::get_rel_ids_from_tables(stmt,
semi_info->left_table_ids_,
semi_tables))) {
LOG_WARN("failed to get rel ids", K(ret));
}
bool find = false;
for (int64_t j = 0; OB_SUCC(ret) && !find && j < temp_helpers.count(); ++j) {
table_ids.reuse();
if (OB_FAIL(ObTransformUtils::get_rel_ids_from_tables(stmt,
temp_helpers.at(j).table_items_,
table_ids))) {
LOG_WARN("failed to get table ids", K(ret));
} else if (!table_ids.is_superset(semi_tables)) {
//do nothing
} else if (OB_FAIL(temp_helpers.at(j).semi_infos_.push_back(semi_info))) {
LOG_WARN("failed to push back expr", K(ret));
} else {
find = true;
}
}
if (OB_SUCC(ret) && !find) {
TableItem *table = stmt->get_table_item_by_id(semi_info->right_table_id_);
LinkTableHelper temp;
temp.dblink_id_ = helper.dblink_id_;
temp.is_reverse_link_ = helper.is_reverse_link_;
temp.parent_table_ = helper.parent_table_;
temp.parent_semi_info_ = helper.parent_semi_info_;
if (OB_FAIL(temp.table_items_.push_back(table))) {
LOG_WARN("failed to push back table item", K(ret));
} else if (OB_FAIL(temp_helpers.push_back(temp))) {
LOG_WARN("failed to push back helper", K(ret));
}
}
}
if (OB_SUCC(ret) && OB_FAIL(append(new_helpers, temp_helpers))) { if (OB_SUCC(ret) && OB_FAIL(append(new_helpers, temp_helpers))) {
LOG_WARN("failed to append helpers", K(ret)); LOG_WARN("failed to append helpers", K(ret));
} }
@ -1240,6 +1286,8 @@ int ObTransformDBlink::formalize_link_table(ObDMLStmt *stmt)
LOG_WARN("failed to formalize table name", K(ret)); LOG_WARN("failed to formalize table name", K(ret));
} else if (OB_FAIL(formalize_select_item(stmt))) { } else if (OB_FAIL(formalize_select_item(stmt))) {
LOG_WARN("failed to formalize select item", K(ret)); LOG_WARN("failed to formalize select item", K(ret));
} else if (OB_FAIL(formalize_bool_select_expr(stmt))) {
LOG_WARN("failed to formalize bool select item", K(ret));
} else if (OB_FAIL(formalize_column_item(stmt))) { } else if (OB_FAIL(formalize_column_item(stmt))) {
LOG_WARN("failed to formalize column item", K(ret)); LOG_WARN("failed to formalize column item", K(ret));
} }
@ -1354,16 +1402,27 @@ int ObTransformDBlink::formalize_select_item(ObDMLStmt *stmt)
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null stmt", K(ret)); LOG_WARN("unexpect null stmt", K(ret));
} else if (stmt->is_select_stmt()) { } else if (stmt->is_select_stmt()) {
ObSEArray<ObString, 4> alias_names;
ObSelectStmt *select_stmt = static_cast<ObSelectStmt *>(stmt); ObSelectStmt *select_stmt = static_cast<ObSelectStmt *>(stmt);
ObIArray<SelectItem> &select_items = select_stmt->get_select_items(); ObIArray<SelectItem> &select_items = select_stmt->get_select_items();
uint64_t id = 0; uint64_t id = 0;
for (int64_t i = 0; OB_SUCC(ret) && i < select_items.count(); ++i) { for (int64_t i = 0; OB_SUCC(ret) && i < select_items.count(); ++i) {
SelectItem &select_item = select_items.at(i); SelectItem &select_item = select_items.at(i);
if (!select_item.is_real_alias_ && bool need_new_alias = false;
if (lib::is_oracle_mode() && !select_item.is_real_alias_ &&
select_item.alias_name_.length() > MAX_COLUMN_NAME_LENGTH_ORACLE_11_g) { select_item.alias_name_.length() > MAX_COLUMN_NAME_LENGTH_ORACLE_11_g) {
// for compatibility with Oracle 11 g, // for compatibility with Oracle 11 g,
// rename the overlength expr. // rename the overlength expr.
need_new_alias = true;
}
for (int64_t j = 0; !need_new_alias && j < i; j ++) {
const ObString &tname = select_items.at(j).alias_name_.empty() ?
select_items.at(j).expr_name_ :
select_items.at(j).alias_name_ ;
if (0 == select_item.alias_name_.case_compare(tname)) {
need_new_alias = true;
}
}
if (need_new_alias) {
int64_t pos = 0; int64_t pos = 0;
const uint64_t OB_MAX_SUBQUERY_NAME_LENGTH = 64; const uint64_t OB_MAX_SUBQUERY_NAME_LENGTH = 64;
const char *ALIAS_NAME = "ALIAS"; const char *ALIAS_NAME = "ALIAS";
@ -1405,6 +1464,52 @@ int ObTransformDBlink::formalize_select_item(ObDMLStmt *stmt)
return ret; return ret;
} }
int ObTransformDBlink::formalize_bool_select_expr(ObDMLStmt *stmt)
{
int ret = OB_SUCCESS;
if (!lib::is_oracle_mode()) {
// do nothing
} else if (OB_ISNULL(stmt) || OB_ISNULL(ctx_) || OB_ISNULL(ctx_->expr_factory_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null stmt", K(ret));
} else if (stmt->is_select_stmt()) {
ObSelectStmt *select_stmt = static_cast<ObSelectStmt *>(stmt);
ObIArray<SelectItem> &select_items = select_stmt->get_select_items();
for (int64_t i = 0; OB_SUCC(ret) && i < select_items.count(); ++i) {
SelectItem &select_item = select_items.at(i);
ObRawExpr *case_when_expr = NULL;
ObConstRawExpr *one_expr = NULL;
ObConstRawExpr *zero_expr = NULL;
bool is_bool_expr = false;
if (OB_ISNULL(select_item.expr_)) {
LOG_WARN("unexpected select item", K(ret));
} else if (OB_FAIL(ObRawExprUtils::check_is_bool_expr(select_item.expr_, is_bool_expr))) {
LOG_WARN("failed to check is bool expr", K(ret));
} else if (!is_bool_expr) {
// do nothing
} else if (OB_FAIL(ObRawExprUtils::build_const_int_expr(*ctx_->expr_factory_,
ObIntType,
1,
one_expr))) {
LOG_WARN("failed to build const number expr", K(ret));
} else if (OB_FAIL(ObRawExprUtils::build_const_int_expr(*ctx_->expr_factory_,
ObIntType,
0,
zero_expr))) {
LOG_WARN("failed to build const number expr", K(ret));
} else if (OB_FAIL(ObRawExprUtils::build_case_when_expr(*ctx_->expr_factory_,
select_item.expr_,
one_expr,
zero_expr,
case_when_expr))) {
LOG_WARN("failed to build case when expr", K(ret));
} else {
select_item.expr_ = case_when_expr;
}
}
}
return ret;
}
int ObTransformDBlink::need_transform(const common::ObIArray<ObParentDMLStmt> &parent_stmts, int ObTransformDBlink::need_transform(const common::ObIArray<ObParentDMLStmt> &parent_stmts,
const int64_t current_level, const int64_t current_level,

View File

@ -153,6 +153,8 @@ private:
int formalize_select_item(ObDMLStmt *stmt); int formalize_select_item(ObDMLStmt *stmt);
int formalize_bool_select_expr(ObDMLStmt *stmt);
int extract_limit(ObDMLStmt *stmt, ObDMLStmt *&dblink_stmt); int extract_limit(ObDMLStmt *stmt, ObDMLStmt *&dblink_stmt);
virtual int need_transform(const common::ObIArray<ObParentDMLStmt> &parent_stmts, virtual int need_transform(const common::ObIArray<ObParentDMLStmt> &parent_stmts,