fix: do not merge view if contained correlated join/semi join condition expr
This commit is contained in:
parent
0de8b3356d
commit
502c2b251d
@ -591,23 +591,16 @@ int ObTransformAggrSubquery::check_aggr_first_validity(ObDMLStmt &stmt,
|
||||
LOG_TRACE("select list is invalid", K(is_valid));
|
||||
OPT_TRACE("subquery select item contain subquery");
|
||||
// 3. check from list is not correlated
|
||||
} else if (OB_FAIL(ObTransformUtils::is_table_item_correlated(query_ref.get_exec_params(),
|
||||
*subquery,
|
||||
is_correlated))) {
|
||||
LOG_WARN("failed to check table item correlated or not", K(ret));
|
||||
// 4. check correlated join on conditions
|
||||
// 5. check correlated semi conditions
|
||||
} else if (OB_FAIL(ObTransformUtils::is_from_item_correlated(query_ref.get_exec_params(),
|
||||
*subquery,
|
||||
is_correlated))) {
|
||||
LOG_WARN("failed to check from item correlated or not", K(ret));
|
||||
} else if (is_correlated) {
|
||||
is_valid = false;
|
||||
OPT_TRACE("subquery`s table item is correlated");
|
||||
// 4. check correlated join on contiditons
|
||||
// 5. check correlated semi contiditons
|
||||
} else if (OB_FAIL(ObTransformUtils::is_join_conditions_correlated(query_ref.get_exec_params(),
|
||||
subquery,
|
||||
is_correlated))) {
|
||||
LOG_WARN("failed to check is join condition correlated", K(ret));
|
||||
} else if (is_correlated) {
|
||||
is_valid = false;
|
||||
OPT_TRACE("subquery`s outer/semi join condition is correlated");
|
||||
// 6. check correlated join contiditons
|
||||
OPT_TRACE("subquery's table item is correlated");
|
||||
// 6. check correlated subquery conditions
|
||||
} else if (OB_FALSE_IT(hint_allowed_transform = (subquery->get_stmt_hint().has_enable_hint(T_UNNEST) ||
|
||||
subquery->get_stmt_hint().has_enable_hint(T_AGGR_FIRST_UNNEST)))) {
|
||||
} else if (OB_FALSE_IT(check_match_index = hint_allowed_transform ? false :
|
||||
@ -1583,24 +1576,18 @@ int ObTransformAggrSubquery::check_join_first_validity(ObQueryRefRawExpr &query_
|
||||
LOG_TRACE("aggr item is invalid", K(is_valid));
|
||||
OPT_TRACE("exists COUNT(NULL)");
|
||||
// never reach
|
||||
// 3. check from list is not correlated
|
||||
} else if (OB_FAIL(ObTransformUtils::is_table_item_correlated(
|
||||
// 3. check from list is not correlated
|
||||
// 4. check correlated join on conditions
|
||||
// 5. check correlated semi conditions
|
||||
} else if (OB_FAIL(ObTransformUtils::is_from_item_correlated(
|
||||
query_ref.get_exec_params(), *subquery, is_correlated))) {
|
||||
LOG_WARN("failed to check subquery table item is correlated", K(ret));
|
||||
LOG_WARN("failed to check if from item is correlated", K(ret));
|
||||
} else if (is_correlated) {
|
||||
is_valid = false;
|
||||
OPT_TRACE("subquery`s table item is correlated");
|
||||
// 4. check correlated join on contiditons
|
||||
// 5. check correlated semi contiditons
|
||||
} else if (OB_FAIL(ObTransformUtils::is_join_conditions_correlated(query_ref.get_exec_params(),
|
||||
subquery,
|
||||
is_correlated))) {
|
||||
LOG_WARN("failed to check join condition correlated", K(ret));
|
||||
} else if (is_correlated) {
|
||||
is_valid = false;
|
||||
OPT_TRACE("subquery`s outer/semi join on condition is correlated");
|
||||
OPT_TRACE("subquery's table item is correlated");
|
||||
|
||||
}
|
||||
// 5. check correlated join contiditons
|
||||
// 5. check correlated subquery conditions
|
||||
for (int64_t i = 0; OB_SUCC(ret) && is_valid && i < subquery->get_condition_size(); ++i) {
|
||||
ObRawExpr *cond = subquery->get_condition_expr(i);
|
||||
if (OB_ISNULL(cond)) {
|
||||
|
@ -491,17 +491,10 @@ int ObTransformDecorrelate::check_lateral_inline_view_validity(TableItem *table_
|
||||
} else if (check_status) {
|
||||
is_valid = false;
|
||||
OPT_TRACE("lateral inline view select expr contain subquery");
|
||||
} else if (OB_FAIL(ObTransformUtils::is_join_conditions_correlated(table_item->exec_params_,
|
||||
ref_query,
|
||||
check_status))) {
|
||||
LOG_WARN("failed to is joined table conditions correlated", K(ret));
|
||||
} else if (check_status) {
|
||||
is_valid = false;
|
||||
OPT_TRACE("lateral inline view contain correlated on condition");
|
||||
} else if (OB_FAIL(ObTransformUtils::is_table_item_correlated(table_item->exec_params_,
|
||||
*ref_query,
|
||||
check_status))) {
|
||||
LOG_WARN("failed to check if subquery contain correlated subquery", K(ret));
|
||||
} else if (OB_FAIL(ObTransformUtils::is_from_item_correlated(table_item->exec_params_,
|
||||
*ref_query,
|
||||
check_status))) {
|
||||
LOG_WARN("failed to check if from items contains correlated subquery", K(ret));
|
||||
} else if (check_status) {
|
||||
is_valid = false;
|
||||
OPT_TRACE("lateral inline view contain correlated table item");
|
||||
|
@ -11240,15 +11240,10 @@ int ObTransformUtils::check_correlated_exprs_can_pullup(const ObIArray<ObExecPar
|
||||
//do nothing
|
||||
} else if (OB_FAIL(check_can_pullup_conds(subquery, has_special_expr))) {
|
||||
LOG_WARN("failed to check can pullup conds", K(ret));
|
||||
} else if (OB_FAIL(is_table_item_correlated(exec_params,
|
||||
subquery,
|
||||
is_correlated))) {
|
||||
LOG_WARN("failed to check", K(ret));
|
||||
} else if (is_correlated) {
|
||||
can_pullup = false;
|
||||
} else if (OB_FAIL(is_join_conditions_correlated(exec_params,
|
||||
&subquery, is_correlated))) {
|
||||
LOG_WARN("failed to check join condition correlated", K(ret));
|
||||
} else if (OB_FAIL(is_from_item_correlated(exec_params,
|
||||
subquery,
|
||||
is_correlated))) {
|
||||
LOG_WARN("failed to check if from item contains correlated exprs", K(ret));
|
||||
} else if (is_correlated) {
|
||||
can_pullup = false;
|
||||
} else if (OB_FAIL(check_correlated_having_expr_can_pullup(exec_params,
|
||||
@ -11616,31 +11611,31 @@ int ObTransformUtils::check_can_pullup_conds(const ObSelectStmt &view, bool &has
|
||||
}
|
||||
|
||||
// link.zt why not considering set stmt ?
|
||||
int ObTransformUtils::is_table_item_correlated(
|
||||
const ObIArray<ObExecParamRawExpr *> &exec_params, const ObSelectStmt &subquery, bool &contains)
|
||||
int ObTransformUtils::is_from_item_correlated(
|
||||
const ObIArray<ObExecParamRawExpr *> &exec_params, const ObSelectStmt &subquery, bool &is_correlated)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t N = subquery.get_table_size();
|
||||
contains = false;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && !contains && i < N; ++i) {
|
||||
is_correlated = false;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && !is_correlated && i < N; ++i) {
|
||||
const TableItem *table = subquery.get_table_item(i);
|
||||
if (OB_ISNULL(table)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("table should not be NULL", K(ret), K(table));
|
||||
} else if (table->is_generated_table() ||
|
||||
table->is_lateral_table()) {
|
||||
if (OB_FAIL(is_correlated_subquery(exec_params, table->ref_query_, contains))) {
|
||||
if (OB_FAIL(is_correlated_subquery(exec_params, table->ref_query_, is_correlated))) {
|
||||
LOG_WARN("check if subquery correlated failed", K(ret));
|
||||
}
|
||||
} else if (table->is_function_table()) {
|
||||
if (OB_FAIL(is_correlated_expr(exec_params, table->function_table_expr_, contains))) {
|
||||
if (OB_FAIL(is_correlated_expr(exec_params, table->function_table_expr_, is_correlated))) {
|
||||
LOG_WARN("failed to check function table expr correlated", K(ret));
|
||||
}
|
||||
} else if (table->is_json_table()) {
|
||||
if (OB_ISNULL(table->json_table_def_->doc_expr_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpect null expr", K(ret));
|
||||
} else if (OB_FAIL(is_correlated_expr(exec_params, table->json_table_def_->doc_expr_, contains))) {
|
||||
} else if (OB_FAIL(is_correlated_expr(exec_params, table->json_table_def_->doc_expr_, is_correlated))) {
|
||||
LOG_WARN("failed to check function table expr correlated", K(ret));
|
||||
}
|
||||
} else if (table->is_values_table()) {
|
||||
@ -11649,30 +11644,18 @@ int ObTransformUtils::is_table_item_correlated(
|
||||
LOG_WARN("unexpect null expr", K(ret));
|
||||
} else {
|
||||
ObIArray<ObRawExpr*> &access_exprs = table->values_table_def_->access_exprs_;
|
||||
for (int64_t j = 0; OB_SUCC(ret) && !contains && j < access_exprs.count(); ++j) {
|
||||
if (OB_FAIL(is_correlated_expr(exec_params, access_exprs.at(j), contains))) {
|
||||
for (int64_t j = 0; OB_SUCC(ret) && !is_correlated && j < access_exprs.count(); ++j) {
|
||||
if (OB_FAIL(is_correlated_expr(exec_params, access_exprs.at(j), is_correlated))) {
|
||||
LOG_WARN("failed to check values table expr correlated", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// check joined table on conditions and semi info semi condition correlated
|
||||
int ObTransformUtils::is_join_conditions_correlated(const ObIArray<ObExecParamRawExpr *> &exec_params,
|
||||
const ObSelectStmt *subquery,
|
||||
bool &is_correlated)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
is_correlated = false;
|
||||
if (OB_ISNULL(subquery)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(subquery), K(ret));
|
||||
} else {
|
||||
const ObIArray<JoinedTable*> &joined_tables = subquery->get_joined_tables();
|
||||
const ObIArray<SemiInfo*> &semi_infos = subquery->get_semi_infos();
|
||||
// check joined table on conditions and semi info semi condition correlated
|
||||
if (OB_SUCC(ret) && !is_correlated) {
|
||||
const ObIArray<JoinedTable*> &joined_tables = subquery.get_joined_tables();
|
||||
const ObIArray<SemiInfo*> &semi_infos = subquery.get_semi_infos();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && !is_correlated && i < joined_tables.count(); ++i) {
|
||||
if (OB_FAIL(check_joined_conditions_correlated(exec_params,
|
||||
joined_tables.at(i),
|
||||
|
@ -1590,13 +1590,9 @@ public:
|
||||
|
||||
static int check_can_pullup_conds(const ObSelectStmt &subquery, bool &has_special_expr);
|
||||
|
||||
static int is_table_item_correlated(const ObIArray<ObExecParamRawExpr *> &exec_params,
|
||||
const ObSelectStmt &subquery,
|
||||
bool &contains);
|
||||
|
||||
static int is_join_conditions_correlated(const ObIArray<ObExecParamRawExpr *> &exec_params,
|
||||
const ObSelectStmt *subquery,
|
||||
bool &is_correlated);
|
||||
static int is_from_item_correlated(const ObIArray<ObExecParamRawExpr *> &exec_params,
|
||||
const ObSelectStmt &subquery,
|
||||
bool &is_correlated);
|
||||
|
||||
static int check_semi_conditions_correlated(const ObIArray<ObExecParamRawExpr *> &exec_params,
|
||||
const SemiInfo *semi_info,
|
||||
|
@ -639,10 +639,10 @@ int ObTransformViewMerge::check_can_be_merged(ObDMLStmt *parent_stmt,
|
||||
LOG_WARN("unexpect null table item", K(ret));
|
||||
} else if (!helper.trans_table->is_lateral_table()) {
|
||||
// do nothing
|
||||
} else if (OB_FAIL(ObTransformUtils::is_table_item_correlated(helper.trans_table->exec_params_,
|
||||
*child_stmt,
|
||||
contain))) {
|
||||
LOG_WARN("failed to check is table item correlated", K(ret));
|
||||
} else if (OB_FAIL(ObTransformUtils::is_from_item_correlated(helper.trans_table->exec_params_,
|
||||
*child_stmt,
|
||||
contain))) {
|
||||
LOG_WARN("failed to check is from item correlated", K(ret));
|
||||
} else if (contain) {
|
||||
can_be = false;
|
||||
OPT_TRACE("lateral inline view has correlated table item, can not merge");
|
||||
|
@ -419,21 +419,14 @@ int ObWhereSubQueryPullup::check_subquery_validity(ObQueryRefRawExpr *query_ref,
|
||||
OPT_TRACE("subquery`s select expr contain subquery");
|
||||
} else if (!is_correlated) {
|
||||
// do nothing
|
||||
} else if (OB_FAIL(ObTransformUtils::is_join_conditions_correlated(query_ref->get_exec_params(),
|
||||
subquery,
|
||||
check_status))) {
|
||||
LOG_WARN("failed to is joined table conditions correlated", K(ret));
|
||||
} else if (check_status) {
|
||||
is_valid = false;
|
||||
OPT_TRACE("subquery`s on condition is correlated");
|
||||
} else if (OB_FAIL(is_where_having_subquery_correlated(query_ref->get_exec_params(), *subquery, check_status))) {
|
||||
LOG_WARN("failed to check select item contain subquery", K(subquery), K(ret));
|
||||
} else if (check_status) {
|
||||
is_valid = false;
|
||||
OPT_TRACE("subquery`s where condition contain correlated subquery");
|
||||
} else if (OB_FAIL(ObTransformUtils::is_table_item_correlated(
|
||||
} else if (OB_FAIL(ObTransformUtils::is_from_item_correlated(
|
||||
query_ref->get_exec_params(), *subquery, check_status))) {
|
||||
LOG_WARN("failed to check if subquery contain correlated subquery", K(ret));
|
||||
LOG_WARN("failed to check if from item contains correlated subquery", K(ret));
|
||||
} else if (check_status) {
|
||||
is_valid = false;
|
||||
OPT_TRACE("subquery`s table item is correlated");
|
||||
@ -1370,17 +1363,10 @@ int ObWhereSubQueryPullup::check_subquery_validity(ObDMLStmt &stmt,
|
||||
//2.check from item correlated
|
||||
if (OB_SUCC(ret) && is_valid) {
|
||||
bool is_correlated = false;
|
||||
if (OB_FAIL(ObTransformUtils::is_join_conditions_correlated(query_ref->get_exec_params(),
|
||||
subquery,
|
||||
is_correlated))) {
|
||||
LOG_WARN("failed to is joined table conditions correlated", K(ret));
|
||||
} else if (is_correlated) {
|
||||
is_valid = false;
|
||||
OPT_TRACE("subquery contain correlated on condition");
|
||||
} else if (OB_FAIL(ObTransformUtils::is_table_item_correlated(query_ref->get_exec_params(),
|
||||
*subquery,
|
||||
is_correlated))) {
|
||||
LOG_WARN("failed to check if subquery contain correlated subquery", K(ret));
|
||||
if (OB_FAIL(ObTransformUtils::is_from_item_correlated(query_ref->get_exec_params(),
|
||||
*subquery,
|
||||
is_correlated))) {
|
||||
LOG_WARN("failed to check if from item contains correlated subquery", K(ret));
|
||||
} else if (is_correlated) {
|
||||
is_valid = false;
|
||||
OPT_TRACE("subquery contain correlated table item");
|
||||
|
Loading…
x
Reference in New Issue
Block a user