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

patch bug fix to open source branch

上级 e03cb033
......@@ -971,10 +971,11 @@ int ObCodeGeneratorImpl::recursive_get_column_expr(const ObColumnRefRawExpr*& co
if (OB_ISNULL(table_item)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else if (!table_item->is_generated_table()) {
column = inner_column;
} else if (OB_FAIL(recursive_get_column_expr(column, *table_item))) {
} else if (table_item->is_generated_table() &&
OB_FAIL(recursive_get_column_expr(inner_column, *table_item))) {
LOG_WARN("faield to recursive get column expr", K(ret));
} else {
column = inner_column;
}
}
}
......
......@@ -5165,10 +5165,11 @@ int ObStaticEngineCG::recursive_get_column_expr(const ObColumnRefRawExpr*& colum
if (OB_ISNULL(table_item)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else if (!table_item->is_generated_table()) {
column = inner_column;
} else if (OB_FAIL(recursive_get_column_expr(column, *table_item))) {
} else if (table_item->is_generated_table() &&
OB_FAIL(recursive_get_column_expr(inner_column, *table_item))) {
LOG_WARN("faield to recursive get column expr", K(ret));
} else {
column = inner_column;
}
}
}
......
......@@ -112,6 +112,8 @@ int ObTableFdItem::check_expr_in_child(const ObRawExpr* expr, const EqualSets& e
if (OB_ISNULL(expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get null expr", K(ret));
} else if (expr->has_flag(CNT_AGG)) {
//do nothing
} else if (expr->get_expr_levels().has_member(stmt_level_)) {
if (child_tables_.is_superset(expr->get_relation_ids())) {
is_in_child = true;
......
......@@ -1590,12 +1590,12 @@ int ObLogPlan::pushdown_on_conditions(
if (OB_ISNULL(qual = joined_table->join_conditions_.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("null expr", K(qual), K(ret));
} else if (RIGHT_OUTER_JOIN == join_type && !qual->get_relation_ids().is_empty() &&
} else if (RIGHT_OUTER_JOIN == join_type &&
qual->get_relation_ids().is_subset(left_table_set)) {
if (OB_FAIL(left_quals.push_back(qual))) {
LOG_WARN("failed to push back expr", K(ret));
}
} else if (LEFT_OUTER_JOIN == join_type && !qual->get_relation_ids().is_empty() &&
} else if (LEFT_OUTER_JOIN == join_type &&
qual->get_relation_ids().is_subset(right_table_set)) {
if (OB_FAIL(right_quals.push_back(qual))) {
LOG_WARN("failed to push back expr", K(ret));
......
......@@ -89,7 +89,7 @@ int ObTransformFullOuterJoin::recursively_eliminate_full_join(
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null.", K(ret));
} else if (table_item->type_ == TableItem::JOINED_TABLE) {
bool has_equal = false;
bool is_valid = false;
JoinedTable* joined_table = static_cast<JoinedTable*>(table_item);
if (OB_ISNULL(joined_table->left_table_) || OB_ISNULL(joined_table->right_table_)) {
ret = OB_ERR_UNEXPECTED;
......@@ -100,11 +100,9 @@ int ObTransformFullOuterJoin::recursively_eliminate_full_join(
LOG_WARN("failed to transform full nl join.", K(ret));
} else if (OB_FAIL(ObTransformUtils::adjust_single_table_ids(joined_table))) {
LOG_WARN("failed to adjust single table ids.", K(ret));
} else if (!joined_table->is_full_join()) {
/* do nothing */
} else if (OB_FAIL(check_join_condition(stmt, joined_table, has_equal))) {
} else if (OB_FAIL(check_full_nl_valid(*stmt, joined_table, is_valid))) {
LOG_WARN("failed to check join condition", K(ret));
} else if (has_equal) {
} else if (!is_valid) {
/* do nothing */
} else if (OB_FAIL(create_view_for_full_nl_join(stmt, joined_table, table_item))) {
LOG_WARN("failed to create view for full nl join.", K(ret));
......@@ -118,17 +116,54 @@ int ObTransformFullOuterJoin::recursively_eliminate_full_join(
return ret;
}
int ObTransformFullOuterJoin::check_join_condition(ObDMLStmt* stmt, JoinedTable* table, bool& has_equal)
int ObTransformFullOuterJoin::check_full_nl_valid(ObDMLStmt &stmt, TableItem* table_item, bool &is_valid)
{
int ret = OB_SUCCESS;
is_valid = true;
if (OB_ISNULL(table_item)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("null joined table.", K(ret));
} else if (table_item->type_ != TableItem::JOINED_TABLE) {
is_valid = false;
} else {
JoinedTable *joined_table = static_cast<JoinedTable *>(table_item);
bool has_euqal = false;
bool has_subquery = false;
if (FULL_OUTER_JOIN != joined_table->joined_type_) {
is_valid = false;
} else if (OB_FAIL(check_join_condition(&stmt,
joined_table,
has_euqal,
has_subquery))) {
LOG_WARN("failed to check join condition", K(ret));
} else if (has_euqal) {
is_valid = false;
} else if (has_subquery) {
ret = OB_NOT_SUPPORTED;
LOG_WARN("full join on subquery not support now!", K(ret));
}
}
return ret;
}
int ObTransformFullOuterJoin::check_join_condition(ObDMLStmt* stmt,
JoinedTable* table,
bool &has_equal,
bool &has_subquery)
{
int ret = OB_SUCCESS;
ObSEArray<uint64_t, 8> left_tables;
ObSEArray<uint64_t, 8> right_tables;
ObSEArray<uint64_t, 8> table_ids;
TableItem* left_table = NULL;
TableItem* right_table = NULL;
ObSEArray<uint64_t, 8> left_table_ids;
ObSEArray<uint64_t, 8> right_table_ids;
TableItem *left_table = NULL;
TableItem *right_table = NULL;
has_equal = false;
if (OB_ISNULL(stmt) || OB_ISNULL(table) || OB_ISNULL(left_table = table->left_table_) ||
OB_ISNULL(right_table = table->right_table_)) {
has_subquery = false;
if (OB_ISNULL(stmt) || OB_ISNULL(table) ||
OB_ISNULL(left_table = table->left_table_) ||
OB_ISNULL(right_table = table->right_table_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null param", K(ret));
} else if (left_table->is_joined_table() &&
......@@ -146,17 +181,38 @@ int ObTransformFullOuterJoin::check_join_condition(ObDMLStmt* stmt, JoinedTable*
ObRawExpr* cond = table->join_conditions_.at(i);
table_ids.reuse();
if (OB_ISNULL(cond)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null condition", K(ret));
} else if (OB_FAIL(ObRawExprUtils::extract_table_ids(cond, table_ids))) {
LOG_WARN("failed to extract table ids", K(ret));
} else if (table_ids.empty()) {
// do nothing
} else if (cond->has_flag(IS_JOIN_COND) && ObOptimizerUtil::overlap(table_ids, left_tables) &&
ObOptimizerUtil::overlap(table_ids, right_tables)) {
has_equal = true;
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null condition", K(ret));
} else if (cond->has_flag(CNT_SUB_QUERY)) {
has_subquery = true;
}
}
if (OB_FAIL(ret)) {
} else if (OB_FAIL(ObRawExprUtils::extract_table_ids(cond, table_ids))) {
LOG_WARN("failed to extract table ids", K(ret));
} else if (table_ids.empty()) {
//do nothing
} else if (cond->has_flag(IS_JOIN_COND)) {
ObRawExpr *left_param = NULL;
ObRawExpr *right_param = NULL;
left_table_ids.reuse();
right_table_ids.reuse();
if (cond->get_param_count() != 2 ||
OB_ISNULL(left_param = cond->get_param_expr(0)) ||
OB_ISNULL(right_param = cond->get_param_expr(1))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null param", K(ret));
} else if (OB_FAIL(ObRawExprUtils::extract_table_ids(left_param, left_table_ids))) {
LOG_WARN("failed to extract table ids", K(ret));
} else if (OB_FAIL(ObRawExprUtils::extract_table_ids(right_param, right_table_ids))) {
LOG_WARN("failed to extract table ids", K(ret));
} else if ((ObOptimizerUtil::is_subset(left_table_ids, left_tables) &&
ObOptimizerUtil::is_subset(right_table_ids, right_tables)) ||
(ObOptimizerUtil::is_subset(left_table_ids, right_tables) &&
ObOptimizerUtil::is_subset(right_table_ids, left_tables))) {
has_equal = true;
}
}
}
return ret;
}
......
......@@ -35,7 +35,12 @@ private:
int transform_full_outer_join(ObDMLStmt*& stmt, bool& trans_happened);
int check_join_condition(ObDMLStmt* stmt, JoinedTable* table, bool& has_equal);
int check_full_nl_valid(ObDMLStmt &stmt, TableItem* table_item, bool &is_valid);
int check_join_condition(ObDMLStmt *stmt,
JoinedTable *table,
bool &has_equal,
bool &has_subquery);
int recursively_eliminate_full_join(ObDMLStmt* stmt, TableItem*& table_item, bool& trans_happened);
......
......@@ -250,10 +250,20 @@ int ObTransformPreProcess::transform_for_grouping_sets_and_multi_rollup(ObDMLStm
ObSelectStmt* view_stmt = NULL;
ObSelectStmt* transform_stmt = NULL;
ObSelectStmt* set_view_stmt = NULL;
bool is_correlated = false;
int32_t stmt_level = select_stmt->get_current_level();
// step 1, creating spj stmt
if (OB_FAIL(ObTransformUtils::create_simple_view(ctx_, select_stmt, view_stmt))) {
LOG_WARN("failed to create spj view.", K(ret));
// step 2, creating temp table
} else if (stmt_level > 0 &&
OB_FAIL(ObTransformUtils::is_correlated_subquery(view_stmt,
stmt_level-1,
is_correlated))) {
LOG_WARN("failed to check is correlated subquery", K(ret));
} else if (is_correlated) {
ret = OB_NOT_SUPPORTED;
LOG_WARN("correlated temp table is not support now!", K(ret));
} else if (OB_FAIL(add_generated_table_as_temp_table(ctx_, select_stmt))) {
LOG_WARN("failed to add generated table as temp table", K(ret));
// setp 3, creating set stmt
......
......@@ -366,23 +366,62 @@ int ObTransformSetOp::is_calc_found_rows_for_union(
}
int ObTransformSetOp::recursive_adjust_order_by(ObSelectStmt* stmt, ObRawExpr* cur_expr, ObRawExpr*& find_expr)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(stmt) || OB_ISNULL(cur_expr)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument, expr is NULL", K(ret));
} else if (cur_expr->is_set_op_expr()) {
ret = replace_select_expr_for_set_op(stmt, cur_expr, find_expr);
} else {
ObRawExpr *new_expr = NULL;
ObRawExprFactory *expr_factory = NULL;
if (OB_ISNULL(expr_factory = ctx_->expr_factory_) ||
OB_ISNULL(ctx_->session_info_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("params have null", K(ret));
} else if (OB_FAIL(ObRawExprUtils::copy_expr(
*expr_factory, cur_expr, new_expr, COPY_REF_DEFAULT))) {
LOG_WARN("failed to copy expr", K(ret));
} else if (OB_FAIL(replace_select_expr_for_set_op(
stmt, new_expr, find_expr))) {
LOG_WARN("failed to replace expr", K(ret));
} else if (OB_FAIL(find_expr->formalize(ctx_->session_info_))) {
LOG_WARN("failed to formalize expr", K(ret));
} else if (OB_FAIL(find_expr->pull_relation_id_and_levels(stmt->get_current_level()))) {
LOG_WARN("failed to pull relation id and levels", K(ret));
}
}
return ret;
}
int ObTransformSetOp::replace_select_expr_for_set_op(ObSelectStmt *stmt,
ObRawExpr *cur_expr,
ObRawExpr *&find_expr)
{
int ret = OB_SUCCESS;
ObRawExpr* set_expr = NULL;
int64_t idx = -1;
if (OB_ISNULL(stmt) || OB_ISNULL(cur_expr)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument, expr is NULL", K(ret));
} else if (OB_ISNULL(set_expr = ObTransformUtils::get_expr_in_cast(cur_expr)) ||
OB_UNLIKELY(!set_expr->is_set_op_expr())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected set expr", K(ret), K(set_expr));
} else if (OB_FALSE_IT(idx = static_cast<ObSetOpRawExpr*>(set_expr)->get_idx())) {
} else if (idx < 0 || idx >= stmt->get_select_item_size()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("union expr param count is wrong", K(ret), K(idx), K(stmt->get_select_item_size()));
} else {
find_expr = stmt->get_select_item(idx).expr_;
} else if (cur_expr->is_set_op_expr()) {
int64_t idx = static_cast<ObSetOpRawExpr*>(cur_expr)->get_idx();
if (idx < 0 || idx >= stmt->get_select_item_size()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("union expr param count is wrong", K(ret), K(idx), K(stmt->get_select_item_size()));
} else {
find_expr = stmt->get_select_item(idx).expr_;
}
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < cur_expr->get_param_count(); ++i) {
ObRawExpr *&expr = cur_expr->get_param_expr(i);
if (OB_ISNULL(expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null expr", K(ret));
} else if (OB_FAIL(SMART_CALL(replace_select_expr_for_set_op(stmt, expr, expr)))) {
LOG_WARN("failed to replace select expr", K(ret));
}
}
find_expr = cur_expr;
}
return ret;
}
......
......@@ -49,6 +49,9 @@ private:
int add_limit_order_for_union(const common::ObIArray<ObParentDMLStmt>& parent_stmts, ObSelectStmt*& stmt);
int check_can_pre_push(ObSelectStmt* stmt, ObSelectStmt* upper_stmt, bool& can_push);
int replace_select_expr_for_set_op(ObSelectStmt *stmt,
ObRawExpr *cur_expr,
ObRawExpr *&find_expr);
private:
DISALLOW_COPY_AND_ASSIGN(ObTransformSetOp);
};
......
......@@ -61,6 +61,43 @@ int ObTransformUtils::is_correlated_expr(const ObRawExpr* expr, int32_t correlat
return ret;
}
int ObTransformUtils::is_correlated_subquery(ObSelectStmt* subquery,
int32_t correlated_level,
bool &is_correlated)
{
int ret = OB_SUCCESS;
is_correlated = false;
ObArray<ObRawExpr*> relation_exprs;
ObArray<ObSelectStmt*> child_stmts;
if (OB_ISNULL(subquery)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null stmt", K(ret));
} else if (OB_FAIL(subquery->get_relation_exprs(relation_exprs))) {
LOG_WARN("get relation exprs failed", K(ret));
}
for (int64_t i = 0; OB_SUCC(ret) && !is_correlated && i < relation_exprs.count(); ++i) {
if (OB_FAIL(is_correlated_expr(relation_exprs.at(i),
correlated_level,
is_correlated))) {
LOG_WARN("failed to check is correlated expr", K(ret));
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(subquery->get_child_stmts(child_stmts))) {
LOG_WARN("get from subquery stmts failed", K(ret));
}
for (int64_t i = 0; OB_SUCC(ret) && !is_correlated && i < child_stmts.count(); ++i) {
if (OB_FAIL(SMART_CALL(is_correlated_subquery(child_stmts.at(i),
correlated_level,
is_correlated)))) {
LOG_WARN("failed to check is correlated subquery", K(ret));
}
}
}
return ret;
}
int ObTransformUtils::is_direct_correlated_expr(
const ObRawExpr* expr, int32_t correlated_level, bool& is_direct_correlated)
{
......
......@@ -83,6 +83,10 @@ private:
public:
static int is_correlated_expr(const ObRawExpr* expr, int32_t correlated_level, bool& is_correlated);
static int is_correlated_subquery(ObSelectStmt* subquery,
int32_t correlated_level,
bool &is_correlated);
static int is_direct_correlated_expr(const ObRawExpr* expr, int32_t correlated_level, bool& is_direct_correlated);
static int has_current_level_column(const ObRawExpr* expr, int32_t curlevel, bool& has);
......
......@@ -2221,25 +2221,25 @@ Outputs & filters:
SQL: select * from t1 left join t2 t on 1=1 where false;
=================================================================
|ID|OPERATOR |NAME |EST. ROWS |COST |
-----------------------------------------------------------------
|0 |NESTED-LOOP OUTER JOIN | |150000000000|126539013545|
|1 | PX COORDINATOR | |500000 |356592 |
|2 | EXCHANGE OUT DISTR |:EX10000|500000 |309262 |
|3 | PX PARTITION ITERATOR | |500000 |309262 |
|4 | TABLE SCAN |t1 |500000 |309262 |
|5 | MATERIAL | |300000 |608147 |
|6 | PX COORDINATOR | |300000 |277391 |
|7 | EXCHANGE OUT DISTR |:EX20000|300000 |192197 |
|8 | PX PARTITION ITERATOR| |300000 |192197 |
|9 | TABLE SCAN |t |300000 |192197 |
=================================================================
========================================================================
|ID|OPERATOR |NAME |EST. ROWS |COST |
------------------------------------------------------------------------
|0 |NESTED-LOOP OUTER JOIN CARTESIAN| |150000000000|113980406167|
|1 | PX COORDINATOR | |500000 |356592 |
|2 | EXCHANGE OUT DISTR |:EX10000|500000 |309262 |
|3 | PX PARTITION ITERATOR | |500000 |309262 |
|4 | TABLE SCAN |t1 |500000 |309262 |
|5 | MATERIAL | |300000 |633265 |
|6 | PX COORDINATOR | |300000 |302508 |
|7 | EXCHANGE OUT DISTR |:EX20000|300000 |217314 |
|8 | PX PARTITION ITERATOR | |300000 |217314 |
|9 | TABLE SCAN |t |300000 |217314 |
========================================================================
Outputs & filters:
-------------------------------------
0 - output([t1.c1], [t1.c2], [t.c1], [t.c2], [t.c3]), filter(nil), startup_filter([0]),
conds([1]), nl_params_(nil), batch_join=false
conds(nil), nl_params_(nil), batch_join=false
1 - output([t1.c1], [t1.c2]), filter(nil)
2 - output([t1.c1], [t1.c2]), filter(nil), dop=1
3 - output([t1.c1], [t1.c2]), filter(nil),
......@@ -2253,7 +2253,7 @@ Outputs & filters:
7 - output([t.c1], [t.c2], [t.c3]), filter(nil), dop=1
8 - output([t.c1], [t.c2], [t.c3]), filter(nil),
force partition granule, asc.
9 - output([t.c1], [t.c2], [t.c3]), filter(nil), startup_filter([0]),
9 - output([t.c1], [t.c2], [t.c3]), filter(nil), startup_filter([1], [0]),
access([t.c1], [t.c2], [t.c3]), partitions(p[0-2]),
is_index_back=false,
range_key([t.c1]), range(MIN ; MAX)always true
......
......@@ -2283,25 +2283,25 @@ Outputs & filters:
SQL: select * from t1 left join t2 t on 1=1 where false;
========================================================
|ID|OPERATOR |NAME |EST. ROWS|COST |
--------------------------------------------------------
|0 |NESTED-LOOP OUTER JOIN | |150000 |127547|
|1 | PX COORDINATOR | |500 |389 |
|2 | EXCHANGE OUT DISTR |:EX10000|500 |342 |
|3 | PX PARTITION ITERATOR | |500 |342 |
|4 | TABLE SCAN |t1 |500 |342 |
|5 | MATERIAL | |300 |621 |
|6 | PX COORDINATOR | |300 |290 |
|7 | EXCHANGE OUT DISTR |:EX20000|300 |205 |
|8 | PX PARTITION ITERATOR| |300 |205 |
|9 | TABLE SCAN |t |300 |205 |
========================================================
===============================================================
|ID|OPERATOR |NAME |EST. ROWS|COST |
---------------------------------------------------------------
|0 |NESTED-LOOP OUTER JOIN CARTESIAN| |150000 |115014|
|1 | PX COORDINATOR | |500 |389 |
|2 | EXCHANGE OUT DISTR |:EX10000|500 |342 |
|3 | PX PARTITION ITERATOR | |500 |342 |
|4 | TABLE SCAN |t1 |500 |342 |
|5 | MATERIAL | |300 |646 |
|6 | PX COORDINATOR | |300 |315 |
|7 | EXCHANGE OUT DISTR |:EX20000|300 |230 |
|8 | PX PARTITION ITERATOR | |300 |230 |
|9 | TABLE SCAN |t |300 |230 |
===============================================================
Outputs & filters:
-------------------------------------
0 - output([t1.c1], [t1.c2], [t.c1], [t.c2], [t.c3]), filter(nil), startup_filter([0]),
conds([1]), nl_params_(nil), batch_join=false
conds(nil), nl_params_(nil), batch_join=false
1 - output([t1.c1], [t1.c2]), filter(nil)
2 - output([t1.c1], [t1.c2]), filter(nil), dop=1
3 - output([t1.c1], [t1.c2]), filter(nil),
......@@ -2315,7 +2315,7 @@ Outputs & filters:
7 - output([t.c1], [t.c2], [t.c3]), filter(nil), dop=1
8 - output([t.c1], [t.c2], [t.c3]), filter(nil),
force partition granule, asc.
9 - output([t.c1], [t.c2], [t.c3]), filter(nil), startup_filter([0]),
9 - output([t.c1], [t.c2], [t.c3]), filter(nil), startup_filter([1], [0]),
access([t.c1], [t.c2], [t.c3]), partitions(p[0-2]),
is_index_back=false,
range_key([t.c1]), range(MIN ; MAX)always true
......@@ -16287,31 +16287,28 @@ Outputs & filters:
SQL: select * from t1 left join t2 on (1 = 0 or t1.c1 = t2.c1) left join t3 on (1=2 and t2.c1 = t3.c1);
==============================================================
|ID|OPERATOR |NAME |EST. ROWS|COST |
--------------------------------------------------------------
|0 |NESTED-LOOP OUTER JOIN | |500 |35573|
|1 | PX COORDINATOR | |500 |1725 |
|2 | EXCHANGE OUT DISTR |:EX10001|500 |1536 |
|3 | MERGE OUTER JOIN | |500 |1536 |
|4 | EXCHANGE IN MERGE SORT DISTR| |500 |389 |
|5 | EXCHANGE OUT DISTR (PKEY) |:EX10000|500 |342 |
|6 | PX PARTITION ITERATOR | |500 |342 |
|7 | TABLE SCAN |t1 |500 |342 |
|8 | SORT | |300 |859 |
|9 | PX PARTITION ITERATOR | |300 |205 |
|10| TABLE SCAN |t2 |300 |205 |
|11| MATERIAL | |200 |426 |
|12| PX COORDINATOR | |200 |205 |
|13| EXCHANGE OUT DISTR |:EX20000|200 |149 |
|14| PX PARTITION ITERATOR | |200 |149 |
|15| TABLE SCAN |t3 |200 |149 |
==============================================================
=============================================================
|ID|OPERATOR |NAME |EST. ROWS|COST|
-------------------------------------------------------------
|0 |NESTED-LOOP OUTER JOIN CARTESIAN| |500 |1825|
|1 | PX COORDINATOR | |500 |1725|
|2 | EXCHANGE OUT DISTR |:EX10001|500 |1536|
|3 | MERGE OUTER JOIN | |500 |1536|
|4 | EXCHANGE IN MERGE SORT DISTR| |500 |389 |
|5 | EXCHANGE OUT DISTR (PKEY) |:EX10000|500 |342 |
|6 | PX PARTITION ITERATOR | |500 |342 |
|7 | TABLE SCAN |t1 |500 |342 |
|8 | SORT | |300 |859 |
|9 | PX PARTITION ITERATOR | |300 |205 |
|10| TABLE SCAN |t2 |300 |205 |
|11| MATERIAL | |0 |101 |
|12| TABLE SCAN |t3 |0 |101 |
=============================================================
Outputs & filters:
-------------------------------------
0 - output([t1.c1], [t1.c2], [t2.c1], [t2.c2], [t2.c3], [t3.c1], [t3.c2], [t3.c3]), filter(nil),
conds([0]), nl_params_(nil), batch_join=false
conds(nil), nl_params_(nil), batch_join=false
1 - output([t1.c1], [t1.c2], [t2.c1], [t2.c2], [t2.c3]), filter(nil)
2 - output([t1.c1], [t1.c2], [t2.c1], [t2.c2], [t2.c3]), filter(nil), dop=1
3 - output([t1.c1], [t1.c2], [t2.c1], [t2.c2], [t2.c3]), filter(nil),
......@@ -16332,14 +16329,10 @@ Outputs & filters:
is_index_back=false,
range_key([t2.c1]), range(MIN ; MAX)always true
11 - output([t3.c1], [t3.c2], [t3.c3]), filter(nil)
12 - output([t3.c1], [t3.c2], [t3.c3]), filter(nil)
13 - output([t3.c1], [t3.c2], [t3.c3]), filter(nil), dop=1
14 - output([t3.c1], [t3.c2], [t3.c3]), filter(nil),
force partition granule, asc.
15 - output([t3.c1], [t3.c2], [t3.c3]), filter(nil),
access([t3.c1], [t3.c2], [t3.c3]), partitions(p[0-1]),
12 - output([t3.c1], [t3.c2], [t3.c3]), filter(nil), startup_filter([0]),
access([t3.c1], [t3.c2], [t3.c3]), partitions(p0),
is_index_back=false,
range_key([t3.c1]), range(MIN ; MAX)always true
range_key([t3.c1]), range(MAX ; MIN)always false
*************** Case 472(end) **************
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册