提交 7dcf2baa 编写于 作者: O obdev 提交者: wangzelin.wzl

Fix query push down and add subquery handling

上级 49d67f86
......@@ -3084,6 +3084,23 @@ bool ObDMLStmt::has_link_table() const
return bret;
}
int ObDMLStmt::get_table_rel_ids(const TableItem &target,
ObSqlBitSet<> &table_set) const
{
int ret = OB_SUCCESS;
if (target.is_joined_table()) {
const JoinedTable &cur_table = static_cast<const JoinedTable &>(target);
for (int64_t i = 0; OB_SUCC(ret) && i < cur_table.single_table_ids_.count(); ++i) {
if (OB_FAIL(table_set.add_member(get_table_bit_index(cur_table.single_table_ids_.at(i))))) {
LOG_WARN("failed to add member", K(ret), K(cur_table.single_table_ids_.at(i)));
}
}
} else if (OB_FAIL(table_set.add_member(get_table_bit_index(target.table_id_)))) {
LOG_WARN("failed to add member", K(ret), K(target.table_id_));
}
return ret;
}
int ObDMLStmt::get_relation_exprs(ObIArray<ObRawExpr*>& rel_array, int32_t ignore_scope /* = 0*/) const
{
int ret = OB_SUCCESS;
......
......@@ -887,6 +887,7 @@ public:
virtual int clear_sharable_expr_reference();
virtual int get_from_subquery_stmts(common::ObIArray<ObSelectStmt*>& child_stmts) const;
int is_referred_by_partitioning_expr(const ObRawExpr* expr, bool& is_referred);
int get_table_rel_ids(const TableItem &target, ObSqlBitSet<> &table_set) const;
int64_t get_table_size() const
{
return table_items_.count();
......
......@@ -342,6 +342,10 @@ int ObTransformQueryPushDown::check_select_item_push_down(ObSelectStmt* select_s
if (OB_ISNULL(select_stmt) || OB_ISNULL(view_stmt)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("stmt is NULL", K(select_stmt), K(view_stmt), K(ret));
} else if (OB_FAIL(check_select_item_subquery(*select_stmt, *view_stmt, check_status))) {
LOG_WARN("failed to check select item has subquery", K(ret));
} else if (!check_status) {
can_be = false;
} else if (view_stmt->is_contains_assignment() || select_stmt->is_contains_assignment()) {
can_be = false;
} else if (OB_FAIL(is_select_item_same(select_stmt, view_stmt, check_status, select_offset, const_select_items))) {
......@@ -358,6 +362,58 @@ int ObTransformQueryPushDown::check_select_item_push_down(ObSelectStmt* select_s
return ret;
}
int ObTransformQueryPushDown::check_select_item_subquery(ObSelectStmt &select_stmt,
ObSelectStmt &view,
bool &can_be)
{
int ret = OB_SUCCESS;
can_be = true;
ObSEArray<ObRawExpr*, 4> column_exprs_from_subquery;
ObRawExpr *expr = NULL;
TableItem *table = NULL;
ObSqlBitSet<> table_set;
if (OB_UNLIKELY(1 != select_stmt.get_table_items().count())
|| OB_ISNULL(table = select_stmt.get_table_item(0))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect select stmt", K(ret), K(select_stmt.get_from_item_size()), K(table));
}
for (int64_t i = 0; OB_SUCC(ret) && i < view.get_select_item_size(); ++i) {
if (OB_ISNULL(expr = view.get_select_item(i).expr_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null expr", K(ret));
} else if (!expr->has_flag(CNT_SUB_QUERY)) {
/* do nothing */
} else if (OB_ISNULL(expr = select_stmt.get_column_expr_by_id(table->table_id_,
i + OB_APP_MIN_COLUMN_ID))) {
/* do nothing */
} else if (OB_FAIL(column_exprs_from_subquery.push_back(expr))) {
LOG_WARN("failed to push back column expr", K(ret));
}
}
if (OB_FAIL(ret)) {
} else if (column_exprs_from_subquery.empty()) {
/* do nothing */
} else if (OB_FAIL(select_stmt.get_table_rel_ids(*table, table_set))) {
LOG_WARN("failed to get rel ids", K(ret));
} else {
ObIArray<ObQueryRefRawExpr*> &subquery_exprs = select_stmt.get_subquery_exprs();
ObSEArray<ObDMLStmt *, 4> ignore_stmts;
ObSEArray<ObRawExpr*, 4> column_exprs;
for (int64_t i = 0; OB_SUCC(ret) && can_be && i < subquery_exprs.count(); ++i) {
column_exprs.reuse();
if(OB_FAIL(ObTransformUtils::extract_column_exprs(subquery_exprs.at(i),
select_stmt.get_current_level(),
table_set, ignore_stmts,
column_exprs))) {
LOG_WARN("extract column exprs failed", K(ret));
} else if (ObOptimizerUtil::overlap(column_exprs, column_exprs_from_subquery)) {
can_be = false;
}
}
}
return ret;
}
int ObTransformQueryPushDown::check_where_condition_push_down(
ObSelectStmt* select_stmt, ObSelectStmt* view_stmt, bool& transform_having, bool& can_be)
{
......
......@@ -56,7 +56,9 @@ private:
int check_select_item_push_down(ObSelectStmt* select_stmt, ObSelectStmt* view_stmt,
common::ObIArray<int64_t>& select_offset, common::ObIArray<SelectItem>& const_select_items, bool& can_be);
int check_select_item_has_subquery(ObSelectStmt& view, bool& has);
int check_select_item_subquery(ObSelectStmt &select_stmt,
ObSelectStmt &view,
bool &can_be);
int adjust_stmt_hints(ObSelectStmt* select_stmt, ObSelectStmt* view_stmt);
......
......@@ -4594,6 +4594,7 @@ int ObTransformUtils::extract_column_exprs(ObDMLStmt* stmt, const int64_t stmt_l
{
int ret = OB_SUCCESS;
ObSEArray<ObRawExpr*, 16> relation_exprs;
ObSEArray<ObSelectStmt*, 16> child_stmts;
bool is_stack_overflow = false;
if (OB_ISNULL(stmt)) {
ret = OB_ERR_UNEXPECTED;
......@@ -4609,7 +4610,19 @@ int ObTransformUtils::extract_column_exprs(ObDMLStmt* stmt, const int64_t stmt_l
LOG_WARN("failed to get relation exprs", K(ret));
} else if (OB_FAIL(SMART_CALL(extract_column_exprs(relation_exprs, stmt_level, table_set, ignore_stmts, columns)))) {
LOG_WARN("failed to extract column exprs", K(ret));
} else { /*do nothing*/
} else if (OB_FAIL(stmt->get_from_subquery_stmts(child_stmts))) {
LOG_WARN("get child stmt failed", K(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < child_stmts.count(); ++i) {
ObSelectStmt* child_stmt = child_stmts.at(i);
if (OB_ISNULL(child_stmt)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid stmt", K(ret));
} else if (OB_FAIL(SMART_CALL(extract_column_exprs(child_stmt, stmt_level, table_set,
ignore_stmts, columns)))) {
LOG_WARN("failed to extract column exprs", K(ret));
}
}
}
return ret;
}
......@@ -6545,7 +6558,7 @@ int ObTransformUtils::convert_select_expr_to_column_expr(const common::ObIArray<
ret = OB_ERR_UNEXPECTED;
LOG_WARN("failed to find select expr inner stmt", K(ret));
} else if (OB_ISNULL(col = outer_stmt.get_column_expr_by_id(table_id, column_id))) {
LOG_WARN("failed to get column expr by id", K(ret));
//do nothing
} else if (OB_FAIL(column_exprs.push_back(col))) {
LOG_WARN("failed to push back column expr", K(ret));
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册