Fix PredicateMoveAround and PredicateDecude bugs
This commit is contained in:
@ -275,7 +275,8 @@ struct ObPCConstParamInfo
|
||||
TO_STRING_KV(K_(const_idx), K_(const_params));
|
||||
bool operator==(const ObPCConstParamInfo &other) const
|
||||
{
|
||||
bool cmp_ret = true;
|
||||
bool cmp_ret = const_idx_.count() == other.const_idx_.count()
|
||||
&& const_params_.count() == other.const_params_.count();
|
||||
for (int i=0; cmp_ret && i < const_idx_.count(); i++) {
|
||||
cmp_ret = const_idx_.at(i) == other.const_idx_.at(i);
|
||||
}
|
||||
|
||||
@ -354,7 +354,7 @@ bool ObGroupByChecker::find_in_rollup(ObRawExpr &expr)
|
||||
}
|
||||
}
|
||||
if (OB_SUCCESS == check_ctx.err_code_ && !found && is_top_select_stmt()) {
|
||||
for (int64_t nth_rollup = 0; !found && nth_rollup < rollup_cnt; ++nth_rollup) {
|
||||
for (int64_t nth_rollup = 0; !found_same_structure && nth_rollup < rollup_cnt; ++nth_rollup) {
|
||||
//in oracle mode, only non static const expr will be replaced later in replace_group_by_exprs
|
||||
if (is_mysql_mode() || !rollup_exprs_->at(nth_rollup)->is_static_const_expr()) {
|
||||
check_ctx.reset();
|
||||
@ -448,10 +448,10 @@ bool ObGroupByChecker::find_in_grouping_sets(ObRawExpr &expr)
|
||||
}
|
||||
}
|
||||
if (OB_SUCCESS == check_ctx.err_code_ && !found && is_top_select_stmt()) {
|
||||
for (int64_t nth_gs = 0; !found && nth_gs < gs_cnt; ++nth_gs) {
|
||||
for (int64_t nth_gs = 0; !found_same_structure && nth_gs < gs_cnt; ++nth_gs) {
|
||||
int64_t group_by_cnt = grouping_sets_exprs_->at(nth_gs).groupby_exprs_.count();
|
||||
//in oracle mode, only non static const expr will be replaced later in replace_group_by_exprs
|
||||
for (int64_t nth_group_by = 0; !found && nth_group_by < group_by_cnt; ++nth_group_by) {
|
||||
for (int64_t nth_group_by = 0; !found_same_structure && nth_group_by < group_by_cnt; ++nth_group_by) {
|
||||
check_ctx.reset();
|
||||
check_ctx.ignore_param_ = true;
|
||||
check_ctx.override_const_compare_ = true;
|
||||
|
||||
@ -627,6 +627,7 @@ int ObPredicateDeduce::get_equal_exprs(ObRawExpr *pred,
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSEArray<ObRawExpr *, 4> first_params;
|
||||
ObSEArray<ObRawExpr *, 4> candi_exprs;
|
||||
int64_t param_idx = -1;
|
||||
ObRawExpr *param_expr = NULL;
|
||||
if (OB_ISNULL(pred) || OB_ISNULL(param_expr = pred->get_param_expr(0))) {
|
||||
@ -637,24 +638,102 @@ int ObPredicateDeduce::get_equal_exprs(ObRawExpr *pred,
|
||||
} else if (ObOptimizerUtil::find_item(input_exprs_, param_expr, ¶m_idx)) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < N; ++i) {
|
||||
ObRawExpr *expr = input_exprs_.at(i);
|
||||
const ObRawExpr *real_expr = expr;
|
||||
bool need_check_type_safe = false;
|
||||
if (!has(graph_, param_idx, i, EQ) || i == param_idx) {
|
||||
// do nothing
|
||||
} else if (OB_ISNULL(expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("input expr is null", K(ret));
|
||||
} else if (!expr->is_column_ref_expr()) {
|
||||
} else if (OB_FAIL(ObRawExprUtils::get_real_expr_without_cast(expr, real_expr))) {
|
||||
LOG_WARN("fail to get real expr", K(ret), K(expr));
|
||||
} else if (!real_expr->is_column_ref_expr()) {
|
||||
// do nothing
|
||||
} else if (expr->get_result_type() != param_expr->get_result_type()) {
|
||||
// do nothing
|
||||
} else if (!ObOptimizerUtil::find_item(target_exprs, expr)) {
|
||||
} else if (!ObOptimizerUtil::find_item(target_exprs, real_expr)) {
|
||||
// do nothing
|
||||
} else if (ObOptimizerUtil::find_item(first_params, expr)) {
|
||||
// do nothing
|
||||
} else if (param_expr->get_result_type().get_type() != expr->get_result_type().get_type()) {
|
||||
need_check_type_safe = is_type_safe(param_idx, i);
|
||||
} else if (ob_is_string_or_lob_type(param_expr->get_result_type().get_type())
|
||||
&& ((param_expr->get_result_type().get_collation_level() != expr->get_result_type().get_collation_level())
|
||||
|| (param_expr->get_result_type().get_collation_type() != expr->get_result_type().get_collation_type()))) {
|
||||
need_check_type_safe = is_type_safe(param_idx, i);
|
||||
} else if (OB_FAIL(equal_exprs.push_back(expr))) {
|
||||
LOG_WARN("failed to push back equal expr", K(ret));
|
||||
}
|
||||
if (OB_SUCC(ret) && need_check_type_safe && OB_FAIL(candi_exprs.push_back(expr))) {
|
||||
LOG_WARN("failed to push back candi exprs whose result type is different from param_expr", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && !candi_exprs.empty()) {
|
||||
bool type_safe = false;
|
||||
if (OB_FAIL(check_cmp_metas_for_general_preds(param_expr, pred, type_safe))) {
|
||||
LOG_WARN("fail to get cmp metas for the param expr", K(ret));
|
||||
} else if (type_safe) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < candi_exprs.count(); ++i) {
|
||||
type_safe = false;
|
||||
if (OB_FAIL(check_cmp_metas_for_general_preds(candi_exprs.at(i), pred, type_safe))) {
|
||||
LOG_WARN("fail to get cmp metas for candi exprs", K(ret));
|
||||
} else if (type_safe && OB_FAIL(equal_exprs.push_back(candi_exprs.at(i)))) {
|
||||
LOG_WARN("failed to push back equal expr", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPredicateDeduce::check_cmp_metas_for_general_preds(ObRawExpr *left_expr, ObRawExpr *pred, bool &type_safe) {
|
||||
int ret = OB_SUCCESS;
|
||||
ObObjMeta cmp_meta;
|
||||
if (OB_ISNULL(left_expr) || OB_ISNULL(pred)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null", K(ret), K(left_expr), K(pred));
|
||||
} else if (T_OP_IN == pred->get_expr_type()) {
|
||||
//params of preds like 'A in (a,b,c...)' has been grouped by result types in pre-process phase,
|
||||
//for example: 'A in (int_a, int_b, float_a, float_b)' <=> A in (int_a, int_b) or A in (float_a, float_b)
|
||||
//so only check the cmp type of A and the first param of row_op
|
||||
ObRawExpr *right_expr = NULL;
|
||||
if (OB_ISNULL(right_expr = pred->get_param_expr(1))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null", K(ret), K(right_expr));
|
||||
} else if (T_OP_ROW != right_expr->get_expr_type()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("the second param of in expr is not row_op", K(ret), K(right_expr->get_expr_type()));
|
||||
} else if (OB_ISNULL(right_expr = right_expr->get_param_expr(0))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null", K(ret), K(right_expr));
|
||||
} else if (OB_FAIL(ObRelationalExprOperator::get_equal_meta(cmp_meta, left_expr->get_result_type(),right_expr->get_result_type()))) {
|
||||
LOG_WARN("failed to get equal meta", K(ret));
|
||||
} else {
|
||||
type_safe = (cmp_meta == cmp_type_);
|
||||
}
|
||||
} else if (T_OP_NE == pred->get_expr_type()) {
|
||||
if (OB_ISNULL(pred->get_param_expr(1))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null", K(ret), K(pred->get_param_expr(1)));
|
||||
} else if (OB_FAIL(ObRelationalExprOperator::get_equal_meta(cmp_meta, left_expr->get_result_type(),pred->get_param_expr(1)->get_result_type()))) {
|
||||
LOG_WARN("failed to get equal meta", K(ret));
|
||||
} else {
|
||||
type_safe = (cmp_meta == cmp_type_);
|
||||
}
|
||||
} else if (T_OP_BTW == pred->get_expr_type()) {
|
||||
if (OB_ISNULL(pred->get_param_expr(1)) || OB_ISNULL(pred->get_param_expr(2))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null", K(ret), K(pred->get_param_expr(1)), K(pred->get_param_expr(2)));
|
||||
} else if (OB_FAIL(ObRelationalExprOperator::get_equal_meta(cmp_meta, left_expr->get_result_type(), pred->get_param_expr(1)->get_result_type()))) {
|
||||
LOG_WARN("failed to get equal meta", K(ret));
|
||||
} else if (cmp_meta != cmp_type_) {
|
||||
} else if (OB_FAIL(ObRelationalExprOperator::get_equal_meta(cmp_meta, left_expr->get_result_type(), pred->get_param_expr(2)->get_result_type()))) {
|
||||
LOG_WARN("failed to get equal meta", K(ret));
|
||||
} else {
|
||||
type_safe = (cmp_meta == cmp_type_);
|
||||
}
|
||||
} else {
|
||||
type_safe = false;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -243,6 +243,8 @@ private:
|
||||
ObRawExpr *right_expr,
|
||||
bool &is_valid);
|
||||
|
||||
int check_cmp_metas_for_general_preds(ObRawExpr *left_pexr, ObRawExpr *pred, bool &type_safe);
|
||||
|
||||
private:
|
||||
ObObjMeta cmp_type_; // the compare meta used by all exprs in the graph
|
||||
|
||||
|
||||
@ -1487,18 +1487,34 @@ int ObTransformPredicateMoveAround::pullup_predicates_from_const_select(ObSelect
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid select list", K(child_select_list.count()), K(parent_select_list), K(ret));
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < child_select_list.count(); ++i) {
|
||||
ObRawExpr *child_expr = child_select_list.at(i);
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < parent_select_list.count(); ++i) {
|
||||
ObRawExpr *child_expr = NULL;
|
||||
ObRawExpr *parent_expr = parent_select_list.at(i);
|
||||
const ObRawExpr *real_parent_expr = parent_select_list.at(i);
|
||||
ObRawExpr *generated_expr = NULL;
|
||||
bool is_not_null = false;
|
||||
if (OB_ISNULL(child_expr) || OB_ISNULL(parent_expr)) {
|
||||
int64_t child_idx = OB_INVALID_ID;
|
||||
if (OB_ISNULL(parent_expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid expr", K(ret));
|
||||
} else if (OB_FAIL(ObRawExprUtils::get_real_expr_without_cast(parent_expr, real_parent_expr))) {
|
||||
LOG_WARN("fail to get real expr", K(ret));
|
||||
} else if (OB_ISNULL(real_parent_expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid expr", K(ret), K(real_parent_expr));
|
||||
} else if (!real_parent_expr->is_set_op_expr()) {
|
||||
// do nothing
|
||||
} else if (FALSE_IT(child_idx = static_cast<const ObSetOpRawExpr *>(real_parent_expr)->get_idx())) {
|
||||
} else if (OB_UNLIKELY(child_idx < 0 || child_idx >= child_select_list.count())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("set op index is invalid", K(ret), K(child_idx));
|
||||
} else if (OB_ISNULL(child_expr = child_select_list.at(child_idx))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid expr", K(ret));
|
||||
} else if (!child_expr->is_const_expr()) {
|
||||
// do nothing
|
||||
} else if (child_expr->get_result_type().is_ext() ||
|
||||
parent_expr->get_result_type().is_ext()) {
|
||||
real_parent_expr->get_result_type().is_ext()) {
|
||||
// OP_EQ between udt not supported
|
||||
} else if (OB_FAIL(ObTransformUtils::is_expr_not_null(
|
||||
ctx_, child_stmt, child_expr, NULLABLE_SCOPE::NS_TOP, is_not_null))) {
|
||||
@ -1519,10 +1535,10 @@ int ObTransformPredicateMoveAround::pullup_predicates_from_const_select(ObSelect
|
||||
&& !(lib::is_oracle_mode() && result.is_null_oracle()))) {
|
||||
//do nothing
|
||||
} else if (OB_FAIL(ObRawExprUtils::build_is_not_null_expr(*ctx_->expr_factory_,
|
||||
parent_expr,
|
||||
const_cast<ObRawExpr*>(real_parent_expr),
|
||||
false,
|
||||
generated_expr))) {
|
||||
LOG_WARN("fail to build is null expr", K(ret), K(parent_expr));
|
||||
LOG_WARN("fail to build is null expr", K(ret), K(real_parent_expr));
|
||||
} else if (OB_ISNULL(generated_expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("is_null expr is null", K(ret));
|
||||
@ -1531,7 +1547,7 @@ int ObTransformPredicateMoveAround::pullup_predicates_from_const_select(ObSelect
|
||||
} else {}
|
||||
} else if (OB_FAIL(ObRawExprUtils::create_double_op_expr(
|
||||
*(ctx_->expr_factory_), ctx_->session_info_, T_OP_EQ,
|
||||
generated_expr, parent_expr, child_expr))) {
|
||||
generated_expr, const_cast<ObRawExpr*>(real_parent_expr), child_expr))) {
|
||||
LOG_WARN("failed to create double op expr", K(ret));
|
||||
}
|
||||
if (OB_FAIL(ret) || NULL == generated_expr) {
|
||||
|
||||
@ -3781,5 +3781,506 @@ Outputs & filters:
|
||||
drop table if exists t1, t2, t3;
|
||||
drop table if exists tt1, tt2, tt3;
|
||||
drop table if exists cghldinf, puzdjypf, pujydypf;
|
||||
drop table if exists v0;
|
||||
CREATE TABLE v0 ( v1 varchar(127));
|
||||
EXPLAIN select * from v0 where v1 in (select -127 minus select _BINARY 'x');
|
||||
Query Plan
|
||||
==============================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
----------------------------------------------
|
||||
|0 |MERGE JOIN | |1 |2 |
|
||||
|1 | SUBPLAN SCAN|VIEW1|1 |1 |
|
||||
|2 | EXPRESSION | |1 |1 |
|
||||
|3 | SORT | |1 |2 |
|
||||
|4 | TABLE SCAN |v0 |1 |2 |
|
||||
==============================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([v0.v1]), filter(nil), rowset=256
|
||||
equal_conds([v0.v1 = VIEW1.-127]), other_conds(nil)
|
||||
merge_directions([ASC])
|
||||
1 - output([VIEW1.-127]), filter(nil), rowset=256
|
||||
access([VIEW1.-127])
|
||||
2 - output([cast(-127, VARCHAR(20))]), filter(nil)
|
||||
values({cast(-127, VARCHAR(20))})
|
||||
3 - output([v0.v1]), filter(nil), rowset=256
|
||||
sort_keys([v0.v1, ASC])
|
||||
4 - output([v0.v1]), filter(nil), rowset=256
|
||||
access([v0.v1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false,
|
||||
range_key([v0.__pk_increment]), range(MIN ; MAX)always true
|
||||
select * from v0 where v1 in (select -127 minus select _BINARY 'x');
|
||||
ERROR HY000: Internal error
|
||||
explain select * from v0 where v1 in (select -127 minus select _BINARY 'x');
|
||||
Query Plan
|
||||
==============================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
----------------------------------------------
|
||||
|0 |MERGE JOIN | |1 |2 |
|
||||
|1 | SUBPLAN SCAN|VIEW1|1 |1 |
|
||||
|2 | EXPRESSION | |1 |1 |
|
||||
|3 | SORT | |1 |2 |
|
||||
|4 | TABLE SCAN |v0 |1 |2 |
|
||||
==============================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([v0.v1]), filter(nil), rowset=256
|
||||
equal_conds([v0.v1 = VIEW1.-127]), other_conds(nil)
|
||||
merge_directions([ASC])
|
||||
1 - output([VIEW1.-127]), filter(nil), rowset=256
|
||||
access([VIEW1.-127])
|
||||
2 - output([cast(-127, VARCHAR(20))]), filter(nil)
|
||||
values({cast(-127, VARCHAR(20))})
|
||||
3 - output([v0.v1]), filter(nil), rowset=256
|
||||
sort_keys([v0.v1, ASC])
|
||||
4 - output([v0.v1]), filter(nil), rowset=256
|
||||
access([v0.v1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false,
|
||||
range_key([v0.__pk_increment]), range(MIN ; MAX)always true
|
||||
drop table if exists v0;
|
||||
|
||||
explain_protocol: 0
|
||||
drop table if exists t1;
|
||||
drop table if exists t2;
|
||||
drop table if exists t3;
|
||||
create table t1(c1 decimal(10), c2 varchar(10), c3 varbinary(20));
|
||||
insert into t1(c1,c2) values(10,'a'),(20,'ab'),(50,'ad'),(100,'b'),(150,'c');
|
||||
create table t2(c1 decimal(20), c2 double, c3 varchar(20));
|
||||
insert into t2(c1,c2,c3) values(10,10,'a'),(20,20,'b'),(50,50,NULL),(100,100,NULL),(150,150,NULL);
|
||||
create table t3(c1 decimal(16), c2 float);
|
||||
insert into t3(c1,c2) values(10,10),(20,20),(50,50),(100,100),(150,150);
|
||||
explain_protocol: 2
|
||||
test IN pred
|
||||
### different accuracy
|
||||
EXPLAIN select t1.c1,t2.c1 from t1,t2 where t1.c1 = t2.c1 and t2.c1 in (10,20,40);
|
||||
Query Plan
|
||||
===========================================
|
||||
|ID|OPERATOR |NAME|EST.ROWS|EST.TIME(us)|
|
||||
-------------------------------------------
|
||||
|0 |HASH JOIN | |4 |5 |
|
||||
|1 | TABLE SCAN|t1 |4 |2 |
|
||||
|2 | TABLE SCAN|t2 |4 |2 |
|
||||
===========================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([t1.c1], [t2.c1]), filter(nil), rowset=256
|
||||
equal_conds([t1.c1 = t2.c1]), other_conds(nil)
|
||||
1 - output([t1.c1]), filter([t1.c1 IN (cast(10, DECIMAL(2, 0)), cast(20, DECIMAL(2, 0)), cast(40, DECIMAL(2, 0)))]), rowset=256
|
||||
access([t1.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t1.__pk_increment]), range(MIN ; MAX)always true
|
||||
2 - output([t2.c1]), filter([t2.c1 IN (cast(10, DECIMAL(2, 0)), cast(20, DECIMAL(2, 0)), cast(40, DECIMAL(2, 0)))]), rowset=256
|
||||
access([t2.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t2.__pk_increment]), range(MIN ; MAX)always true
|
||||
select t1.c1,t2.c1 from t1,t2 where t1.c1 = t2.c1 and t2.c1 in (10,20,40);
|
||||
+------+------+
|
||||
| c1 | c1 |
|
||||
+------+------+
|
||||
| 10 | 10 |
|
||||
| 20 | 20 |
|
||||
+------+------+
|
||||
EXPLAIN select t1.c1,t2.c1 from t1,t2 where t1.c1 = t2.c1 and t1.c1 in (10,20,40);
|
||||
Query Plan
|
||||
===========================================
|
||||
|ID|OPERATOR |NAME|EST.ROWS|EST.TIME(us)|
|
||||
-------------------------------------------
|
||||
|0 |HASH JOIN | |4 |5 |
|
||||
|1 | TABLE SCAN|t1 |4 |2 |
|
||||
|2 | TABLE SCAN|t2 |4 |2 |
|
||||
===========================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([t1.c1], [t2.c1]), filter(nil), rowset=256
|
||||
equal_conds([t1.c1 = t2.c1]), other_conds(nil)
|
||||
1 - output([t1.c1]), filter([t1.c1 IN (cast(10, DECIMAL(2, 0)), cast(20, DECIMAL(2, 0)), cast(40, DECIMAL(2, 0)))]), rowset=256
|
||||
access([t1.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t1.__pk_increment]), range(MIN ; MAX)always true
|
||||
2 - output([t2.c1]), filter([t2.c1 IN (cast(10, DECIMAL(2, 0)), cast(20, DECIMAL(2, 0)), cast(40, DECIMAL(2, 0)))]), rowset=256
|
||||
access([t2.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t2.__pk_increment]), range(MIN ; MAX)always true
|
||||
select t1.c1,t2.c1 from t1,t2 where t1.c1 = t2.c1 and t1.c1 in (10,20,40);
|
||||
+------+------+
|
||||
| c1 | c1 |
|
||||
+------+------+
|
||||
| 10 | 10 |
|
||||
| 20 | 20 |
|
||||
+------+------+
|
||||
EXPLAIN select t1.c1,t2.c1 from t1,t2,t3 where t1.c1 = t3.c1 and t2.c1 = t3.c1 and t1.c1 in (10,20,40);
|
||||
Query Plan
|
||||
============================================
|
||||
|ID|OPERATOR |NAME|EST.ROWS|EST.TIME(us)|
|
||||
--------------------------------------------
|
||||
|0 |HASH JOIN | |4 |8 |
|
||||
|1 | TABLE SCAN |t3 |4 |2 |
|
||||
|2 | HASH JOIN | |4 |5 |
|
||||
|3 | TABLE SCAN|t1 |4 |2 |
|
||||
|4 | TABLE SCAN|t2 |4 |2 |
|
||||
============================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([t1.c1], [t2.c1]), filter(nil), rowset=256
|
||||
equal_conds([t1.c1 = t3.c1]), other_conds(nil)
|
||||
1 - output([t3.c1]), filter([t3.c1 IN (cast(10, DECIMAL(2, 0)), cast(20, DECIMAL(2, 0)), cast(40, DECIMAL(2, 0)))]), rowset=256
|
||||
access([t3.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t3.__pk_increment]), range(MIN ; MAX)always true
|
||||
2 - output([t1.c1], [t2.c1]), filter(nil), rowset=256
|
||||
equal_conds([t1.c1 = t2.c1]), other_conds(nil)
|
||||
3 - output([t1.c1]), filter([t1.c1 IN (cast(10, DECIMAL(2, 0)), cast(20, DECIMAL(2, 0)), cast(40, DECIMAL(2, 0)))]), rowset=256
|
||||
access([t1.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t1.__pk_increment]), range(MIN ; MAX)always true
|
||||
4 - output([t2.c1]), filter([t2.c1 IN (cast(10, DECIMAL(2, 0)), cast(20, DECIMAL(2, 0)), cast(40, DECIMAL(2, 0)))]), rowset=256
|
||||
access([t2.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t2.__pk_increment]), range(MIN ; MAX)always true
|
||||
select t1.c1,t2.c1 from t1,t2,t3 where t1.c1 = t3.c1 and t2.c1 = t3.c1 and t1.c1 in (10,20,40);
|
||||
+------+------+
|
||||
| c1 | c1 |
|
||||
+------+------+
|
||||
| 10 | 10 |
|
||||
| 20 | 20 |
|
||||
+------+------+
|
||||
### different types
|
||||
####preds are 'cast(t1.c1,double) = cast(t3.c2,double)' and 'cast(t3.c2,double) in (10,20,40)'. cast(t3.c2,double) is not column ref, so 't1.c1 in (10,20,40)' won't be deduced.
|
||||
EXPLAIN select * from t1,t3 where t1.c1 = t3.c2 and t3.c2 in (10,20,40);
|
||||
Query Plan
|
||||
===========================================
|
||||
|ID|OPERATOR |NAME|EST.ROWS|EST.TIME(us)|
|
||||
-------------------------------------------
|
||||
|0 |HASH JOIN | |5 |5 |
|
||||
|1 | TABLE SCAN|t3 |4 |3 |
|
||||
|2 | TABLE SCAN|t1 |5 |2 |
|
||||
===========================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([t1.c1], [t1.c2], [t1.c3], [t3.c1], [t3.c2]), filter(nil), rowset=256
|
||||
equal_conds([cast(t1.c1, DOUBLE(-1, -1)) = cast(t3.c2, DOUBLE(-1, -1))]), other_conds(nil)
|
||||
1 - output([t3.c2], [t3.c1], [cast(t3.c2, DOUBLE(-1, -1))]), filter([cast(t3.c2, DOUBLE(-1, -1)) IN (cast(10, DOUBLE(-1, -1)), cast(20, DOUBLE(-1, -1)),
|
||||
cast(40, DOUBLE(-1, -1)))]), rowset=256
|
||||
access([t3.c2], [t3.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t3.__pk_increment]), range(MIN ; MAX)always true
|
||||
2 - output([t1.c1], [t1.c2], [t1.c3]), filter(nil), rowset=256
|
||||
access([t1.c1], [t1.c2], [t1.c3]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false,
|
||||
range_key([t1.__pk_increment]), range(MIN ; MAX)always true
|
||||
select * from t1,t3 where t1.c1 = t3.c2 and t3.c2 in (10,20,40);
|
||||
+------+------+------+------+------+
|
||||
| c1 | c2 | c3 | c1 | c2 |
|
||||
+------+------+------+------+------+
|
||||
| 10 | a | NULL | 10 | 10 |
|
||||
| 20 | ab | NULL | 20 | 20 |
|
||||
+------+------+------+------+------+
|
||||
####different collection type
|
||||
EXPLAIN select * from t1,t2 where t1.c3 = t2.c3 and t2.c3 in ('a','b','c');
|
||||
Query Plan
|
||||
===========================================
|
||||
|ID|OPERATOR |NAME|EST.ROWS|EST.TIME(us)|
|
||||
-------------------------------------------
|
||||
|0 |HASH JOIN | |4 |7 |
|
||||
|1 | TABLE SCAN|t2 |4 |2 |
|
||||
|2 | TABLE SCAN|t1 |5 |2 |
|
||||
===========================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([t1.c1], [t1.c2], [t1.c3], [t2.c1], [t2.c2], [t2.c3]), filter(nil), rowset=256
|
||||
equal_conds([t1.c3 = cast(t2.c3, VARCHAR(1048576))]), other_conds(nil)
|
||||
1 - output([t2.c3], [t2.c1], [t2.c2]), filter([t2.c3 IN ('a', 'b', 'c')]), rowset=256
|
||||
access([t2.c3], [t2.c1], [t2.c2]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t2.__pk_increment]), range(MIN ; MAX)always true
|
||||
2 - output([t1.c3], [t1.c1], [t1.c2]), filter(nil), rowset=256
|
||||
access([t1.c3], [t1.c1], [t1.c2]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false,
|
||||
range_key([t1.__pk_increment]), range(MIN ; MAX)always true
|
||||
select * from t1,t2 where t1.c3 = t2.c3 and t2.c3 in ('a','b','c');
|
||||
+------+------+------+------+------+------+
|
||||
| c1 | c2 | c3 | c1 | c2 | c3 |
|
||||
+------+------+------+------+------+------+
|
||||
+------+------+------+------+------+------+
|
||||
EXPLAIN select * from t1,t2 where t1.c3 = t2.c3 and t1.c3 in ('a','b','c');
|
||||
Query Plan
|
||||
===========================================
|
||||
|ID|OPERATOR |NAME|EST.ROWS|EST.TIME(us)|
|
||||
-------------------------------------------
|
||||
|0 |HASH JOIN | |1 |5 |
|
||||
|1 | TABLE SCAN|t2 |1 |2 |
|
||||
|2 | TABLE SCAN|t1 |4 |2 |
|
||||
===========================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([t1.c1], [t1.c2], [t1.c3], [t2.c1], [t2.c2], [t2.c3]), filter(nil), rowset=256
|
||||
equal_conds([t1.c3 = cast(t2.c3, VARCHAR(1048576))]), other_conds(nil)
|
||||
1 - output([t2.c3], [t2.c1], [t2.c2], [cast(t2.c3, VARCHAR(1048576))]), filter([cast(t2.c3, VARCHAR(1048576)) IN (cast('a', VARCHAR(1048576)), cast('b',
|
||||
VARCHAR(1048576)), cast('c', VARCHAR(1048576)))]), rowset=256
|
||||
access([t2.c3], [t2.c1], [t2.c2]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t2.__pk_increment]), range(MIN ; MAX)always true
|
||||
2 - output([t1.c3], [t1.c1], [t1.c2]), filter([t1.c3 IN (cast('a', VARCHAR(1048576)), cast('b', VARCHAR(1048576)), cast('c', VARCHAR(1048576)))]), rowset=256
|
||||
access([t1.c3], [t1.c1], [t1.c2]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t1.__pk_increment]), range(MIN ; MAX)always true
|
||||
select * from t1,t2 where t1.c3 = t2.c3 and t1.c3 in ('a','b','c');
|
||||
+------+------+------+------+------+------+
|
||||
| c1 | c2 | c3 | c1 | c2 | c3 |
|
||||
+------+------+------+------+------+------+
|
||||
+------+------+------+------+------+------+
|
||||
test NOT EQUAL
|
||||
EXPLAIN select t1.c1,t2.c1 from t1,t2 where t1.c1 = t2.c1 and t2.c1 <> 20;
|
||||
Query Plan
|
||||
===========================================
|
||||
|ID|OPERATOR |NAME|EST.ROWS|EST.TIME(us)|
|
||||
-------------------------------------------
|
||||
|0 |HASH JOIN | |4 |5 |
|
||||
|1 | TABLE SCAN|t1 |4 |2 |
|
||||
|2 | TABLE SCAN|t2 |4 |2 |
|
||||
===========================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([t1.c1], [t2.c1]), filter(nil), rowset=256
|
||||
equal_conds([t1.c1 = t2.c1]), other_conds(nil)
|
||||
1 - output([t1.c1]), filter([t1.c1 != cast(20, DECIMAL(2, 0))]), rowset=256
|
||||
access([t1.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t1.__pk_increment]), range(MIN ; MAX)always true
|
||||
2 - output([t2.c1]), filter([t2.c1 != cast(20, DECIMAL(2, 0))]), rowset=256
|
||||
access([t2.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t2.__pk_increment]), range(MIN ; MAX)always true
|
||||
select t1.c1,t2.c1 from t1,t2 where t1.c1 = t2.c1 and t2.c1 <> 20;
|
||||
+------+------+
|
||||
| c1 | c1 |
|
||||
+------+------+
|
||||
| 10 | 10 |
|
||||
| 50 | 50 |
|
||||
| 100 | 100 |
|
||||
| 150 | 150 |
|
||||
+------+------+
|
||||
EXPLAIN select t1.c1,t2.c1 from t1,t2 where t1.c1 = t2.c1 and t1.c1 <> 20;
|
||||
Query Plan
|
||||
===========================================
|
||||
|ID|OPERATOR |NAME|EST.ROWS|EST.TIME(us)|
|
||||
-------------------------------------------
|
||||
|0 |HASH JOIN | |4 |5 |
|
||||
|1 | TABLE SCAN|t1 |4 |2 |
|
||||
|2 | TABLE SCAN|t2 |4 |2 |
|
||||
===========================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([t1.c1], [t2.c1]), filter(nil), rowset=256
|
||||
equal_conds([t1.c1 = t2.c1]), other_conds(nil)
|
||||
1 - output([t1.c1]), filter([t1.c1 != cast(20, DECIMAL(2, 0))]), rowset=256
|
||||
access([t1.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t1.__pk_increment]), range(MIN ; MAX)always true
|
||||
2 - output([t2.c1]), filter([t2.c1 != cast(20, DECIMAL(2, 0))]), rowset=256
|
||||
access([t2.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t2.__pk_increment]), range(MIN ; MAX)always true
|
||||
select t1.c1,t2.c1 from t1,t2 where t1.c1 = t2.c1 and t1.c1 <> 20;
|
||||
+------+------+
|
||||
| c1 | c1 |
|
||||
+------+------+
|
||||
| 10 | 10 |
|
||||
| 50 | 50 |
|
||||
| 100 | 100 |
|
||||
| 150 | 150 |
|
||||
+------+------+
|
||||
EXPLAIN select t1.c1,t2.c1 from t1,t2,t3 where t1.c1 = t3.c1 and t2.c1 = t3.c1 and t1.c1 <>20;
|
||||
Query Plan
|
||||
============================================
|
||||
|ID|OPERATOR |NAME|EST.ROWS|EST.TIME(us)|
|
||||
--------------------------------------------
|
||||
|0 |HASH JOIN | |4 |8 |
|
||||
|1 | TABLE SCAN |t3 |4 |2 |
|
||||
|2 | HASH JOIN | |4 |5 |
|
||||
|3 | TABLE SCAN|t1 |4 |2 |
|
||||
|4 | TABLE SCAN|t2 |4 |2 |
|
||||
============================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([t1.c1], [t2.c1]), filter(nil), rowset=256
|
||||
equal_conds([t1.c1 = t3.c1]), other_conds(nil)
|
||||
1 - output([t3.c1]), filter([t3.c1 != cast(20, DECIMAL(2, 0))]), rowset=256
|
||||
access([t3.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t3.__pk_increment]), range(MIN ; MAX)always true
|
||||
2 - output([t1.c1], [t2.c1]), filter(nil), rowset=256
|
||||
equal_conds([t1.c1 = t2.c1]), other_conds(nil)
|
||||
3 - output([t1.c1]), filter([t1.c1 != cast(20, DECIMAL(2, 0))]), rowset=256
|
||||
access([t1.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t1.__pk_increment]), range(MIN ; MAX)always true
|
||||
4 - output([t2.c1]), filter([t2.c1 != cast(20, DECIMAL(2, 0))]), rowset=256
|
||||
access([t2.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t2.__pk_increment]), range(MIN ; MAX)always true
|
||||
select t1.c1,t2.c1 from t1,t2,t3 where t1.c1 = t3.c1 and t2.c1 = t3.c1 and t1.c1 <>20;
|
||||
+------+------+
|
||||
| c1 | c1 |
|
||||
+------+------+
|
||||
| 10 | 10 |
|
||||
| 50 | 50 |
|
||||
| 100 | 100 |
|
||||
| 150 | 150 |
|
||||
+------+------+
|
||||
EXPLAIN select * from t1,t3 where t1.c1 = t3.c2 and t3.c2 <> 20;
|
||||
Query Plan
|
||||
===========================================
|
||||
|ID|OPERATOR |NAME|EST.ROWS|EST.TIME(us)|
|
||||
-------------------------------------------
|
||||
|0 |HASH JOIN | |5 |6 |
|
||||
|1 | TABLE SCAN|t3 |4 |3 |
|
||||
|2 | TABLE SCAN|t1 |5 |2 |
|
||||
===========================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([t1.c1], [t1.c2], [t1.c3], [t3.c1], [t3.c2]), filter(nil), rowset=256
|
||||
equal_conds([cast(t1.c1, DOUBLE(-1, -1)) = cast(t3.c2, DOUBLE(-1, -1))]), other_conds(nil)
|
||||
1 - output([t3.c2], [t3.c1], [cast(t3.c2, DOUBLE(-1, -1))]), filter([cast(t3.c2, DOUBLE(-1, -1)) != cast(20, DOUBLE(-1, -1))]), rowset=256
|
||||
access([t3.c2], [t3.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t3.__pk_increment]), range(MIN ; MAX)always true
|
||||
2 - output([t1.c1], [t1.c2], [t1.c3]), filter(nil), rowset=256
|
||||
access([t1.c1], [t1.c2], [t1.c3]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false,
|
||||
range_key([t1.__pk_increment]), range(MIN ; MAX)always true
|
||||
select * from t1,t3 where t1.c1 = t3.c2 and t3.c2 <> 20;
|
||||
+------+------+------+------+------+
|
||||
| c1 | c2 | c3 | c1 | c2 |
|
||||
+------+------+------+------+------+
|
||||
| 10 | a | NULL | 10 | 10 |
|
||||
| 50 | ad | NULL | 50 | 50 |
|
||||
| 100 | b | NULL | 100 | 100 |
|
||||
| 150 | c | NULL | 150 | 150 |
|
||||
+------+------+------+------+------+
|
||||
|
||||
test BETWEEN
|
||||
### differnt types
|
||||
EXPLAIN select t3.c1,t2.c1 from t3,t2 where t3.c2 = t2.c2 and t2.c2 between 10 and cast(100 as float);
|
||||
Query Plan
|
||||
===========================================
|
||||
|ID|OPERATOR |NAME|EST.ROWS|EST.TIME(us)|
|
||||
-------------------------------------------
|
||||
|0 |HASH JOIN | |1 |4 |
|
||||
|1 | TABLE SCAN|t3 |1 |2 |
|
||||
|2 | TABLE SCAN|t2 |1 |2 |
|
||||
===========================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([t3.c1], [t2.c1]), filter(nil), rowset=256
|
||||
equal_conds([cast(t3.c2, DOUBLE(-1, -1)) = t2.c2]), other_conds(nil)
|
||||
1 - output([t3.c1], [cast(t3.c2, DOUBLE(-1, -1))]), filter([(T_OP_BTW, cast(t3.c2, DOUBLE(-1, -1)), cast(10, DOUBLE(-1, -1)), cast(cast(100, FLOAT(0,
|
||||
-1)), DOUBLE(-1, -1)))]), rowset=256
|
||||
access([t3.c2], [t3.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t3.__pk_increment]), range(MIN ; MAX)always true
|
||||
2 - output([t2.c2], [t2.c1]), filter([(T_OP_BTW, t2.c2, cast(10, DOUBLE(-1, -1)), cast(cast(100, FLOAT(0, -1)), DOUBLE(-1, -1)))]), rowset=256
|
||||
access([t2.c2], [t2.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t2.__pk_increment]), range(MIN ; MAX)always true
|
||||
select t3.c1,t2.c1 from t3,t2 where t3.c2 = t2.c2 and t2.c2 between 10 and cast(100 as float);
|
||||
+------+------+
|
||||
| c1 | c1 |
|
||||
+------+------+
|
||||
| 10 | 10 |
|
||||
| 20 | 20 |
|
||||
| 50 | 50 |
|
||||
| 100 | 100 |
|
||||
+------+------+
|
||||
EXPLAIN select t3.c1,t2.c1 from t3,t2 where t3.c2 = t2.c2 and t3.c2 between 10 and cast(100 as float);
|
||||
Query Plan
|
||||
===========================================
|
||||
|ID|OPERATOR |NAME|EST.ROWS|EST.TIME(us)|
|
||||
-------------------------------------------
|
||||
|0 |HASH JOIN | |1 |5 |
|
||||
|1 | TABLE SCAN|t3 |1 |2 |
|
||||
|2 | TABLE SCAN|t2 |5 |2 |
|
||||
===========================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([t3.c1], [t2.c1]), filter(nil), rowset=256
|
||||
equal_conds([cast(t3.c2, DOUBLE(-1, -1)) = t2.c2]), other_conds(nil)
|
||||
1 - output([t3.c1], [cast(t3.c2, DOUBLE(-1, -1))]), filter([(T_OP_BTW, cast(t3.c2, DOUBLE(-1, -1)), cast(10, DOUBLE(-1, -1)), cast(cast(100, FLOAT(0,
|
||||
-1)), DOUBLE(-1, -1)))]), rowset=256
|
||||
access([t3.c2], [t3.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t3.__pk_increment]), range(MIN ; MAX)always true
|
||||
2 - output([t2.c2], [t2.c1]), filter(nil), rowset=256
|
||||
access([t2.c2], [t2.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false,
|
||||
range_key([t2.__pk_increment]), range(MIN ; MAX)always true
|
||||
select t3.c1,t2.c1 from t3,t2 where t3.c2 = t2.c2 and t3.c2 between 10 and cast(100 as float);
|
||||
+------+------+
|
||||
| c1 | c1 |
|
||||
+------+------+
|
||||
| 10 | 10 |
|
||||
| 20 | 20 |
|
||||
| 50 | 50 |
|
||||
| 100 | 100 |
|
||||
+------+------+
|
||||
|
||||
test LIKE
|
||||
EXPLAIN select t1.c1,t2.c1 from t1,t2 where t1.c2 = t2.c3 and t2.c3 like 'a_';
|
||||
Query Plan
|
||||
===========================================
|
||||
|ID|OPERATOR |NAME|EST.ROWS|EST.TIME(us)|
|
||||
-------------------------------------------
|
||||
|0 |HASH JOIN | |1 |5 |
|
||||
|1 | TABLE SCAN|t1 |1 |2 |
|
||||
|2 | TABLE SCAN|t2 |1 |2 |
|
||||
===========================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([t1.c1], [t2.c1]), filter(nil), rowset=256
|
||||
equal_conds([t1.c2 = t2.c3]), other_conds(nil)
|
||||
1 - output([t1.c2], [t1.c1]), filter([(T_OP_LIKE, t1.c2, 'a_', '\\')]), rowset=256
|
||||
access([t1.c2], [t1.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t1.__pk_increment]), range(MIN ; MAX)always true
|
||||
2 - output([t2.c3], [t2.c1]), filter([(T_OP_LIKE, t2.c3, 'a_', '\\')]), rowset=256
|
||||
access([t2.c3], [t2.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t2.__pk_increment]), range(MIN ; MAX)always true
|
||||
select t1.c1,t2.c1 from t1,t2 where t1.c2 = t2.c3 and t2.c3 like 'a_';
|
||||
+------+------+
|
||||
| c1 | c1 |
|
||||
+------+------+
|
||||
+------+------+
|
||||
EXPLAIN select t1.c1,t2.c1 from t1,t2 where t1.c2 = t2.c3 and t1.c2 like 'a_';
|
||||
Query Plan
|
||||
===========================================
|
||||
|ID|OPERATOR |NAME|EST.ROWS|EST.TIME(us)|
|
||||
-------------------------------------------
|
||||
|0 |HASH JOIN | |1 |5 |
|
||||
|1 | TABLE SCAN|t1 |1 |2 |
|
||||
|2 | TABLE SCAN|t2 |1 |2 |
|
||||
===========================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([t1.c1], [t2.c1]), filter(nil), rowset=256
|
||||
equal_conds([t1.c2 = t2.c3]), other_conds(nil)
|
||||
1 - output([t1.c2], [t1.c1]), filter([(T_OP_LIKE, t1.c2, 'a_', '\\')]), rowset=256
|
||||
access([t1.c2], [t1.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t1.__pk_increment]), range(MIN ; MAX)always true
|
||||
2 - output([t2.c3], [t2.c1]), filter([(T_OP_LIKE, t2.c3, 'a_', '\\')]), rowset=256
|
||||
access([t2.c3], [t2.c1]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t2.__pk_increment]), range(MIN ; MAX)always true
|
||||
select t1.c1,t2.c1 from t1,t2 where t1.c2 = t2.c3 and t1.c2 like 'a_';
|
||||
+------+------+
|
||||
| c1 | c1 |
|
||||
+------+------+
|
||||
+------+------+
|
||||
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
drop table t3;
|
||||
|
||||
USE DB_PREDICATE_DEDUCE;
|
||||
drop database DB_PREDICATE_DEDUCE;
|
||||
|
||||
@ -432,5 +432,59 @@ drop table if exists tt1, tt2, tt3;
|
||||
drop table if exists cghldinf, puzdjypf, pujydypf;
|
||||
--enable_warnings
|
||||
|
||||
#Bugfix:https://work.aone.alibaba-inc.com/issue/47217185
|
||||
--disable_warnings
|
||||
drop table if exists v0;
|
||||
--enable_warnings
|
||||
CREATE TABLE v0 ( v1 varchar(127));
|
||||
select * from v0 where v1 in (select -127 minus select _BINARY 'x');
|
||||
explain select * from v0 where v1 in (select -127 minus select _BINARY 'x');
|
||||
drop table if exists v0;
|
||||
|
||||
|
||||
#Bugfix:https://work.aone.alibaba-inc.com/issue/47186369
|
||||
--explain_protocol 0
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
drop table if exists t2;
|
||||
drop table if exists t3;
|
||||
--enable_warnings
|
||||
create table t1(c1 decimal(10), c2 varchar(10), c3 varbinary(20));
|
||||
insert into t1(c1,c2) values(10,'a'),(20,'ab'),(50,'ad'),(100,'b'),(150,'c');
|
||||
create table t2(c1 decimal(20), c2 double, c3 varchar(20));
|
||||
insert into t2(c1,c2,c3) values(10,10,'a'),(20,20,'b'),(50,50,NULL),(100,100,NULL),(150,150,NULL);
|
||||
create table t3(c1 decimal(16), c2 float);
|
||||
insert into t3(c1,c2) values(10,10),(20,20),(50,50),(100,100),(150,150);
|
||||
--explain_protocol 2
|
||||
--echo test IN pred
|
||||
### different accuracy
|
||||
select t1.c1,t2.c1 from t1,t2 where t1.c1 = t2.c1 and t2.c1 in (10,20,40);
|
||||
select t1.c1,t2.c1 from t1,t2 where t1.c1 = t2.c1 and t1.c1 in (10,20,40);
|
||||
select t1.c1,t2.c1 from t1,t2,t3 where t1.c1 = t3.c1 and t2.c1 = t3.c1 and t1.c1 in (10,20,40);
|
||||
### different types
|
||||
####preds are 'cast(t1.c1,double) = cast(t3.c2,double)' and 'cast(t3.c2,double) in (10,20,40)'. cast(t3.c2,double) is not column ref, so 't1.c1 in (10,20,40)' won't be deduced.
|
||||
select * from t1,t3 where t1.c1 = t3.c2 and t3.c2 in (10,20,40);
|
||||
####different collection type
|
||||
select * from t1,t2 where t1.c3 = t2.c3 and t2.c3 in ('a','b','c');
|
||||
select * from t1,t2 where t1.c3 = t2.c3 and t1.c3 in ('a','b','c');
|
||||
--echo test NOT EQUAL
|
||||
select t1.c1,t2.c1 from t1,t2 where t1.c1 = t2.c1 and t2.c1 <> 20;
|
||||
select t1.c1,t2.c1 from t1,t2 where t1.c1 = t2.c1 and t1.c1 <> 20;
|
||||
select t1.c1,t2.c1 from t1,t2,t3 where t1.c1 = t3.c1 and t2.c1 = t3.c1 and t1.c1 <>20;
|
||||
select * from t1,t3 where t1.c1 = t3.c2 and t3.c2 <> 20;
|
||||
|
||||
--echo test BETWEEN
|
||||
### differnt types
|
||||
select t3.c1,t2.c1 from t3,t2 where t3.c2 = t2.c2 and t2.c2 between 10 and cast(100 as float);
|
||||
select t3.c1,t2.c1 from t3,t2 where t3.c2 = t2.c2 and t3.c2 between 10 and cast(100 as float);
|
||||
|
||||
--echo test LIKE
|
||||
select t1.c1,t2.c1 from t1,t2 where t1.c2 = t2.c3 and t2.c3 like 'a_';
|
||||
select t1.c1,t2.c1 from t1,t2 where t1.c2 = t2.c3 and t1.c2 like 'a_';
|
||||
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
drop table t3;
|
||||
|
||||
USE DB_PREDICATE_DEDUCE;
|
||||
drop database DB_PREDICATE_DEDUCE;
|
||||
|
||||
Reference in New Issue
Block a user