Fix dblink bugs

This commit is contained in:
xianyu-w
2023-07-24 12:18:37 +00:00
committed by ob-robot
parent 6aa97ebc17
commit 96331c927c
2 changed files with 97 additions and 19 deletions

View File

@ -290,12 +290,12 @@ int ObTransformDBlink::inner_reverse_link_table(ObDMLStmt *stmt, uint64_t target
}
}
if (OB_FAIL(ret)) {
} else if (has_invalid_link_expr(*stmt, has_invalid_expr)) {
} else if (OB_FAIL(has_invalid_link_expr(*stmt, has_invalid_expr))) {
LOG_WARN("failed to check stmt has invalid link expr", K(ret));
} else if (has_invalid_expr) {
ret = OB_NOT_SUPPORTED;
LOG_WARN("dblink write udf or user variable not supported", K(ret));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "dblink write udf or user variable");
LOG_WARN("dblink write with special expr not supported", K(ret));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "dblink write with user defined function/variable/type");
} else if (OB_FAIL(reverse_link_tables(stmt->get_table_items(), target_dblink_id))) {
LOG_WARN("failed to reverse link table", K(ret));
} else if (OB_FAIL(formalize_link_table(stmt))) {
@ -460,14 +460,50 @@ int ObTransformDBlink::pack_link_table(ObDMLStmt *stmt, bool &trans_happened)
int ObTransformDBlink::has_invalid_link_expr(ObDMLStmt &stmt, bool &has_invalid_expr)
{
int ret = OB_SUCCESS;
if (OB_FAIL(stmt.has_special_expr(CNT_PL_UDF, has_invalid_expr))) {
LOG_WARN("failed to check stmt has special expr", K(ret));
} else if (has_invalid_expr) {
} else if (OB_FAIL(stmt.has_special_expr(CNT_SO_UDF, has_invalid_expr))) {
LOG_WARN("failed to check stmt has special expr", K(ret));
} else if (has_invalid_expr) {
} else if (OB_FAIL(stmt.has_special_expr(CNT_USER_VARIABLE, has_invalid_expr))) {
LOG_WARN("failed to check stmt has special expr", K(ret));
ObSEArray<ObRawExpr*, 16> exprs;
has_invalid_expr = false;
if (OB_FAIL(stmt.get_relation_exprs(exprs))) {
LOG_WARN("failed to get relation exprs", K(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && !has_invalid_expr && i < exprs.count(); i++) {
bool is_valid = false;
if (OB_FAIL(check_link_expr_valid(exprs.at(i), is_valid))) {
LOG_WARN("failed to check link expr valid", KPC(exprs.at(i)), K(ret));
} else if (!is_valid) {
has_invalid_expr = true;
}
}
}
return ret;
}
int ObTransformDBlink::check_link_expr_valid(ObRawExpr *expr, bool &is_valid)
{
int ret = OB_SUCCESS;
is_valid = false;
if (OB_ISNULL(expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null expr", K(ret));
} else if (expr->has_flag(CNT_PL_UDF) ||
expr->has_flag(CNT_SO_UDF) ||
expr->has_flag(CNT_USER_VARIABLE)) {
// special flag is invalid
} else if (T_FUN_APPROX_COUNT_DISTINCT_SYNOPSIS == expr->get_expr_type() ||
T_FUN_APPROX_COUNT_DISTINCT_SYNOPSIS_MERGE == expr->get_expr_type() ||
T_FUN_SYS_ESTIMATE_NDV == expr->get_expr_type()) {
// special function is invalid
} else if (expr->get_result_type().is_ext()) {
// special type is invalid
} else {
is_valid = true;
}
if (OB_SUCC(ret) && !is_valid) {
LOG_DEBUG("expr should not appear in the link stmt", KPC(expr));
}
for (int64_t i = 0; OB_SUCC(ret) && is_valid && i < expr->get_param_count(); i++) {
ret = SMART_CALL(check_link_expr_valid(expr->get_param_expr(i), is_valid));
}
return ret;
}
@ -1115,7 +1151,7 @@ int ObTransformDBlink::get_from_item_idx(ObDMLStmt *stmt,
table_ids.reuse();
if (OB_FAIL(ObTransformUtils::get_rel_ids_from_table(
stmt,
stmt->get_table_item_by_id(stmt->get_from_item(i).table_id_),
stmt->get_table_item(stmt->get_from_item(i)),
table_ids))) {
LOG_WARN("failed to get rel ids", K(ret));
} else if (!table_ids.overlap(expr->get_relation_ids())) {
@ -1210,13 +1246,15 @@ int ObTransformDBlink::has_none_pushdown_expr(ObRawExpr* expr,
{
int ret = OB_SUCCESS;
has = false;
bool is_valid = true;
if (OB_ISNULL(expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null expr", K(ret));
} else if (OB_FAIL(check_link_expr_valid(expr, is_valid))) {
LOG_WARN("failed to check link expr valid", K(ret));
} else if (!is_valid) {
has = true;
} else if (expr->has_flag(CNT_ROWNUM) ||
expr->has_flag(CNT_PL_UDF) ||
expr->has_flag(CNT_SO_UDF) ||
expr->has_flag(CNT_USER_VARIABLE) ||
expr->has_flag(CNT_SEQ_EXPR)) {
has = true;
} else if (expr->has_flag(IS_SUB_QUERY)) {
@ -1408,7 +1446,7 @@ int ObTransformDBlink::formalize_select_item(ObDMLStmt *stmt)
for (int64_t i = 0; OB_SUCC(ret) && i < select_items.count(); ++i) {
SelectItem &select_item = select_items.at(i);
bool need_new_alias = false;
if (lib::is_oracle_mode() && !select_item.is_real_alias_ &&
if (lib::is_oracle_mode() &&
select_item.alias_name_.length() > MAX_COLUMN_NAME_LENGTH_ORACLE_11_g) {
// for compatibility with Oracle 11 g,
// rename the overlength expr.
@ -1473,19 +1511,57 @@ int ObTransformDBlink::formalize_bool_select_expr(ObDMLStmt *stmt)
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null stmt", K(ret));
} else if (stmt->is_select_stmt()) {
// formalize bool select expr p like `a > b` as
// case when p then 1 when not p then 0 else null
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);
ObCaseOpRawExpr *case_when_expr = NULL;
ObRawExpr *bool_expr = select_item.expr_;
ObRawExpr *not_expr = NULL;
ObConstRawExpr *one_expr = NULL;
ObConstRawExpr *zero_expr = NULL;
ObRawExpr *null_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) {
// TODO : BOOL SELECT ITEM NOT SUPPORTED IN ORACLE MODE
} 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_not_expr(*ctx_->expr_factory_,
bool_expr,
not_expr))) {
LOG_WARN("failed to build not 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_null_expr(*ctx_->expr_factory_, null_expr))) {
LOG_WARN("faile to build null expr", K(ret));
} else if (OB_FAIL(ctx_->expr_factory_->create_raw_expr(T_OP_CASE, case_when_expr))) {
LOG_WARN("create case expr failed", K(ret));
} else if (OB_ISNULL(case_when_expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("bool select item for oracle dblink not supported", K(ret));
LOG_WARN("get unexpected null", K(ret), K(case_when_expr));
} else if (OB_FAIL(case_when_expr->add_when_param_expr(bool_expr))) {
LOG_WARN("failed to add when param expr", K(ret));
} else if (OB_FAIL(case_when_expr->add_then_param_expr(one_expr))) {
LOG_WARN("failed to add then expr", K(ret));
} else if (OB_FAIL(case_when_expr->add_when_param_expr(not_expr))) {
LOG_WARN("failed to add when param expr", K(ret));
} else if (OB_FAIL(case_when_expr->add_then_param_expr(zero_expr))) {
LOG_WARN("failed to add then expr", K(ret));
} else {
case_when_expr->set_default_param_expr(null_expr);
select_item.expr_ = case_when_expr;
}
}
}

View File

@ -168,6 +168,8 @@ private:
int has_invalid_link_expr(ObDMLStmt &stmt, bool &has_invalid_expr);
static int check_link_expr_valid(ObRawExpr *expr, bool &is_valid);
DISALLOW_COPY_AND_ASSIGN(ObTransformDBlink);
private: