fix mysql calc found rows bug, adjust semi condition check
This commit is contained in:
parent
8d81ad6ed1
commit
996696c528
@ -1144,39 +1144,35 @@ int ObCodeGeneratorImpl::convert_limit(ObLogLimit& op, const PhyOpsDesc& child_o
|
||||
ObSqlExpression* limit_expr = NULL;
|
||||
ObSqlExpression* offset_expr = NULL;
|
||||
ObSqlExpression* percent_expr = NULL;
|
||||
if (OB_FAIL(op.need_calc_found_rows(need_calc))) {
|
||||
LOG_WARN("need_calc_found_rows() fails unexpectedly", K(ret));
|
||||
} else {
|
||||
phy_op->set_calc_found_rows(need_calc);
|
||||
phy_op->set_is_top_limit(op.is_top_limit());
|
||||
phy_op->set_is_fetch_with_ties(op.is_fetch_with_ties());
|
||||
limit_raw_expr = op.get_limit_count();
|
||||
offset_raw_expr = op.get_limit_offset();
|
||||
percent_raw_expr = op.get_limit_percent();
|
||||
if (NULL != limit_raw_expr) {
|
||||
if (OB_FAIL(generate_sql_expr(
|
||||
phy_op->get_sql_expression_factory(), limit_raw_expr, *child_ops.at(0).second, limit_expr))) {
|
||||
LOG_WARN("Generation of sql expression fails", K(ret));
|
||||
}
|
||||
phy_op->set_calc_found_rows(op.get_is_calc_found_rows());
|
||||
phy_op->set_is_top_limit(op.is_top_limit());
|
||||
phy_op->set_is_fetch_with_ties(op.is_fetch_with_ties());
|
||||
limit_raw_expr = op.get_limit_count();
|
||||
offset_raw_expr = op.get_limit_offset();
|
||||
percent_raw_expr = op.get_limit_percent();
|
||||
if (NULL != limit_raw_expr) {
|
||||
if (OB_FAIL(generate_sql_expr(
|
||||
phy_op->get_sql_expression_factory(), limit_raw_expr, *child_ops.at(0).second, limit_expr))) {
|
||||
LOG_WARN("Generation of sql expression fails", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret) && NULL != offset_raw_expr) {
|
||||
if (OB_FAIL(generate_sql_expr(
|
||||
phy_op->get_sql_expression_factory(), offset_raw_expr, *child_ops.at(0).second, offset_expr))) {
|
||||
LOG_WARN("Generation of sql expression fails", K(ret));
|
||||
}
|
||||
if (OB_SUCC(ret) && NULL != offset_raw_expr) {
|
||||
if (OB_FAIL(generate_sql_expr(
|
||||
phy_op->get_sql_expression_factory(), offset_raw_expr, *child_ops.at(0).second, offset_expr))) {
|
||||
LOG_WARN("Generation of sql expression fails", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret) && NULL != percent_raw_expr) {
|
||||
if (OB_FAIL(generate_sql_expr(
|
||||
phy_op->get_sql_expression_factory(), percent_raw_expr, *child_ops.at(0).second, percent_expr))) {
|
||||
LOG_WARN("Generation of sql expression fails", K(ret));
|
||||
}
|
||||
if (OB_SUCC(ret) && NULL != percent_raw_expr) {
|
||||
if (OB_FAIL(generate_sql_expr(
|
||||
phy_op->get_sql_expression_factory(), percent_raw_expr, *child_ops.at(0).second, percent_expr))) {
|
||||
LOG_WARN("Generation of sql expression fails", K(ret));
|
||||
}
|
||||
if (OB_SUCC(ret) && op.is_fetch_with_ties()) {
|
||||
if (OB_FAIL(set_sort_columns_for_fetch(phy_op, input_row_desc, op.get_expected_ordering()))) {
|
||||
LOG_WARN("failed to set limit sort columns for fetch", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && op.is_fetch_with_ties()) {
|
||||
if (OB_FAIL(set_sort_columns_for_fetch(phy_op, input_row_desc, op.get_expected_ordering()))) {
|
||||
LOG_WARN("failed to set limit sort columns for fetch", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -587,36 +587,33 @@ int ObStaticEngineCG::generate_spec(ObLogLimit& op, ObLimitSpec& spec, const boo
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
UNUSED(in_root_job);
|
||||
if (OB_FAIL(op.need_calc_found_rows(spec.calc_found_rows_))) {
|
||||
LOG_WARN("get calc found rows failed", K(ret));
|
||||
} else {
|
||||
spec.is_top_limit_ = op.is_top_limit();
|
||||
spec.is_fetch_with_ties_ = op.is_fetch_with_ties();
|
||||
if (NULL != op.get_limit_count()) {
|
||||
CK(op.get_limit_count()->get_result_type().is_integer_type());
|
||||
OZ(generate_rt_expr(*op.get_limit_count(), spec.limit_expr_));
|
||||
OZ(mark_expr_self_produced(op.get_limit_count()));
|
||||
}
|
||||
if (NULL != op.get_limit_offset()) {
|
||||
CK(op.get_limit_offset()->get_result_type().is_integer_type());
|
||||
OZ(generate_rt_expr(*op.get_limit_offset(), spec.offset_expr_));
|
||||
OZ(mark_expr_self_produced(op.get_limit_offset()));
|
||||
}
|
||||
if (NULL != op.get_limit_percent()) {
|
||||
CK(op.get_limit_percent()->get_result_type().is_double());
|
||||
OZ(generate_rt_expr(*op.get_limit_percent(), spec.percent_expr_));
|
||||
OZ(mark_expr_self_produced(op.get_limit_percent()));
|
||||
}
|
||||
if (OB_SUCC(ret) && op.is_fetch_with_ties()) {
|
||||
OZ(spec.sort_columns_.init(op.get_expected_ordering().count()));
|
||||
FOREACH_CNT_X(it, op.get_expected_ordering(), OB_SUCC(ret))
|
||||
{
|
||||
CK(NULL != it->expr_);
|
||||
ObExpr* e = NULL;
|
||||
OZ(generate_rt_expr(*it->expr_, e));
|
||||
OZ(mark_expr_self_produced(it->expr_));
|
||||
OZ(spec.sort_columns_.push_back(e));
|
||||
}
|
||||
spec.calc_found_rows_ = op.get_is_calc_found_rows();
|
||||
spec.is_top_limit_ = op.is_top_limit();
|
||||
spec.is_fetch_with_ties_ = op.is_fetch_with_ties();
|
||||
if (NULL != op.get_limit_count()) {
|
||||
CK(op.get_limit_count()->get_result_type().is_integer_type());
|
||||
OZ(generate_rt_expr(*op.get_limit_count(), spec.limit_expr_));
|
||||
OZ(mark_expr_self_produced(op.get_limit_count()));
|
||||
}
|
||||
if (NULL != op.get_limit_offset()) {
|
||||
CK(op.get_limit_offset()->get_result_type().is_integer_type());
|
||||
OZ(generate_rt_expr(*op.get_limit_offset(), spec.offset_expr_));
|
||||
OZ(mark_expr_self_produced(op.get_limit_offset()));
|
||||
}
|
||||
if (NULL != op.get_limit_percent()) {
|
||||
CK(op.get_limit_percent()->get_result_type().is_double());
|
||||
OZ(generate_rt_expr(*op.get_limit_percent(), spec.percent_expr_));
|
||||
OZ(mark_expr_self_produced(op.get_limit_percent()));
|
||||
}
|
||||
if (OB_SUCC(ret) && op.is_fetch_with_ties()) {
|
||||
OZ(spec.sort_columns_.init(op.get_expected_ordering().count()));
|
||||
FOREACH_CNT_X(it, op.get_expected_ordering(), OB_SUCC(ret))
|
||||
{
|
||||
CK(NULL != it->expr_);
|
||||
ObExpr* e = NULL;
|
||||
OZ(generate_rt_expr(*it->expr_, e));
|
||||
OZ(mark_expr_self_produced(it->expr_));
|
||||
OZ(spec.sort_columns_.push_back(e));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -696,8 +693,6 @@ int ObStaticEngineCG::generate_spec(
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("null pointer", K(ret));
|
||||
} else if (raw_expr->has_flag(IS_CONST) || raw_expr->has_flag(IS_CONST_EXPR)) {
|
||||
// distinct const value, 这里需要注意:distinct 1被跳过了,
|
||||
// 但ObMergeDistinct中,如果没有distinct列,则默认所有值都相等,这个语义正好是符合预期的。
|
||||
continue;
|
||||
} else if (OB_FAIL(generate_rt_expr(*raw_expr, expr))) {
|
||||
LOG_WARN("failed to generate rt expr", K(ret));
|
||||
@ -717,7 +712,7 @@ int ObStaticEngineCG::generate_spec(
|
||||
cmp_func.cmp_func_ = ObDatumFuncs::get_nullsafe_cmp_func(
|
||||
expr->datum_meta_.type_,
|
||||
expr->datum_meta_.type_,
|
||||
NULL_LAST,//这里null last还是first无所谓
|
||||
NULL_LAST,
|
||||
expr->datum_meta_.cs_type_,
|
||||
lib::is_oracle_mode());
|
||||
ObHashFunc hash_func;
|
||||
@ -746,8 +741,6 @@ int ObStaticEngineCG::generate_spec(
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("null pointer", K(ret));
|
||||
} else if (raw_expr->has_flag(IS_CONST) || raw_expr->has_flag(IS_CONST_EXPR)) {
|
||||
// distinct const value, 这里需要注意:distinct 1被跳过了,
|
||||
// 但ObMergeDistinct中,如果没有distinct列,则默认所有值都相等,这个语义正好是符合预期的。
|
||||
continue;
|
||||
} else if (OB_FAIL(generate_rt_expr(*raw_expr, expr))) {
|
||||
LOG_WARN("failed to generate rt expr", K(ret));
|
||||
|
@ -36,8 +36,7 @@ int ObLogLimit::copy_without_child(ObLogicalOperator*& out)
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("failed to cast ObLogicalOperator * to ObLogLimit *", K(ret));
|
||||
} else {
|
||||
limit->set_calc_found_rows(is_calc_found_rows_);
|
||||
limit->set_has_union_child(has_union_child_);
|
||||
limit->set_is_calc_found_rows(is_calc_found_rows_);
|
||||
limit->set_fetch_with_ties(is_fetch_with_ties());
|
||||
limit->set_limit_count(limit_count_);
|
||||
limit->set_limit_offset(limit_offset_);
|
||||
@ -239,7 +238,6 @@ uint64_t ObLogLimit::hash(uint64_t seed) const
|
||||
{
|
||||
uint64_t hash_value = seed;
|
||||
hash_value = do_hash(is_calc_found_rows_, hash_value);
|
||||
hash_value = do_hash(has_union_child_, hash_value);
|
||||
hash_value = do_hash(is_top_limit_, hash_value);
|
||||
hash_value = ObOptimizerUtil::hash_expr(limit_count_, hash_value);
|
||||
hash_value = ObOptimizerUtil::hash_expr(limit_offset_, hash_value);
|
||||
|
@ -21,7 +21,6 @@ public:
|
||||
ObLogLimit(ObLogPlan& plan)
|
||||
: ObLogicalOperator(plan),
|
||||
is_calc_found_rows_(false),
|
||||
has_union_child_(false),
|
||||
is_top_limit_(false),
|
||||
is_fetch_with_ties_(false),
|
||||
limit_count_(NULL),
|
||||
@ -55,26 +54,11 @@ public:
|
||||
{
|
||||
limit_percent_ = limit_percent;
|
||||
}
|
||||
void set_calc_found_rows(bool found_rows)
|
||||
void set_is_calc_found_rows(bool found_rows)
|
||||
{
|
||||
is_calc_found_rows_ = found_rows;
|
||||
}
|
||||
int need_calc_found_rows(bool& need_calc)
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
need_calc = false;
|
||||
if (is_top_limit_ && is_calc_found_rows_) {
|
||||
need_calc = true;
|
||||
} else if (is_top_limit_ && has_union_child_) {
|
||||
need_calc = true;
|
||||
} else { /* Do nothing */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
void set_has_union_child(bool has_union_child)
|
||||
{
|
||||
has_union_child_ = has_union_child;
|
||||
}
|
||||
bool get_is_calc_found_rows() { return is_calc_found_rows_; }
|
||||
void set_top_limit(bool is_top_limit)
|
||||
{
|
||||
is_top_limit_ = is_top_limit;
|
||||
@ -83,10 +67,6 @@ public:
|
||||
{
|
||||
return is_top_limit_;
|
||||
}
|
||||
bool has_union_child()
|
||||
{
|
||||
return has_union_child_;
|
||||
}
|
||||
virtual int est_cost() override;
|
||||
virtual int allocate_granule_pre(AllocGIContext &ctx) override;
|
||||
virtual int allocate_granule_post(AllocGIContext &ctx) override;
|
||||
@ -110,7 +90,6 @@ public:
|
||||
|
||||
private:
|
||||
bool is_calc_found_rows_;
|
||||
bool has_union_child_;
|
||||
bool is_top_limit_;
|
||||
bool is_fetch_with_ties_;
|
||||
ObRawExpr* limit_count_;
|
||||
|
@ -5030,34 +5030,24 @@ int ObLogPlan::candi_allocate_limit(ObIArray<OrderItem>& order_items)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObDMLStmt* stmt = NULL;
|
||||
bool has_union_child = false;
|
||||
if (OB_ISNULL(stmt = get_stmt())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("get unexpected null", K(get_stmt()), K(ret));
|
||||
} else if (stmt->is_set_stmt()) {
|
||||
has_union_child = static_cast<ObSelectStmt*>(stmt)->get_set_op() == ObSelectStmt::UNION;
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(candi_allocate_limit(stmt->get_limit_expr(),
|
||||
stmt->get_offset_expr(),
|
||||
stmt->get_limit_percent_expr(),
|
||||
order_items,
|
||||
has_union_child,
|
||||
stmt->is_calc_found_rows(),
|
||||
stmt->has_top_limit(),
|
||||
stmt->is_fetch_with_ties()))) {
|
||||
LOG_WARN("failed to allocate limit operator", K(ret));
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
}
|
||||
} else if (OB_FAIL(candi_allocate_limit(stmt->get_limit_expr(),
|
||||
stmt->get_offset_expr(),
|
||||
stmt->get_limit_percent_expr(),
|
||||
order_items,
|
||||
stmt->is_calc_found_rows(),
|
||||
stmt->has_top_limit(),
|
||||
stmt->is_fetch_with_ties()))) {
|
||||
LOG_WARN("failed to allocate limit operator", K(ret));
|
||||
} else { /*do nothing*/}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLogPlan::candi_allocate_limit(ObRawExpr* limit_expr, ObRawExpr* offset_expr, ObRawExpr* percent_expr,
|
||||
ObIArray<OrderItem>& expect_ordering, const bool has_union_child, const bool is_calc_found_rows,
|
||||
const bool is_top_limit, const bool is_fetch_with_ties)
|
||||
ObIArray<OrderItem>& expect_ordering, const bool is_calc_found_rows, const bool is_top_limit,
|
||||
const bool is_fetch_with_ties)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
CandidatePlan temp_plan;
|
||||
@ -5108,7 +5098,6 @@ int ObLogPlan::candi_allocate_limit(ObRawExpr* limit_expr, ObRawExpr* offset_exp
|
||||
offset_expr,
|
||||
percent_expr,
|
||||
expect_ordering,
|
||||
has_union_child,
|
||||
is_calc_found_rows,
|
||||
is_top_limit,
|
||||
is_fetch_with_ties))) {
|
||||
@ -5320,8 +5309,8 @@ int ObLogPlan::if_plan_need_limit(ObLogicalOperator* top, ObRawExpr* limit_expr,
|
||||
}
|
||||
|
||||
int ObLogPlan::allocate_limit_as_top(ObLogicalOperator*& old_top, ObRawExpr* limit_expr, ObRawExpr* offset_expr,
|
||||
ObRawExpr* percent_expr, ObIArray<OrderItem>& expect_ordering, const bool has_union_child,
|
||||
const bool is_calc_found_rows, const bool is_top_limit, const bool is_fetch_with_ties)
|
||||
ObRawExpr* percent_expr, ObIArray<OrderItem>& expect_ordering, const bool is_calc_found_rows,
|
||||
const bool is_top_limit, const bool is_fetch_with_ties)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObLogLimit* limit = NULL;
|
||||
@ -5336,8 +5325,7 @@ int ObLogPlan::allocate_limit_as_top(ObLogicalOperator*& old_top, ObRawExpr* lim
|
||||
limit->set_limit_offset(offset_expr);
|
||||
limit->set_limit_percent(percent_expr);
|
||||
limit->set_child(ObLogicalOperator::first_child, old_top);
|
||||
limit->set_has_union_child(has_union_child);
|
||||
limit->set_calc_found_rows(is_calc_found_rows);
|
||||
limit->set_is_calc_found_rows(is_calc_found_rows);
|
||||
limit->set_top_limit(is_top_limit);
|
||||
limit->set_fetch_with_ties(is_fetch_with_ties);
|
||||
if (OB_FAIL(limit->set_expected_ordering(expect_ordering))) {
|
||||
|
@ -640,8 +640,8 @@ public:
|
||||
/** @brief Allocate LIMIT on top of plan candidates */
|
||||
int candi_allocate_limit(common::ObIArray<OrderItem>& order_items);
|
||||
int candi_allocate_limit(ObRawExpr* limit_expr, ObRawExpr* offset_expr, ObRawExpr* percent_expr,
|
||||
common::ObIArray<OrderItem>& expect_ordering, const bool has_union_child, const bool is_calc_found_rows,
|
||||
const bool is_top_limit, const bool is_fetch_with_ties);
|
||||
common::ObIArray<OrderItem>& expect_ordering, const bool is_calc_found_rows, const bool is_top_limit,
|
||||
const bool is_fetch_with_ties);
|
||||
|
||||
int is_plan_reliable(const ObLogicalOperator* root, bool& is_reliable);
|
||||
|
||||
@ -660,8 +660,8 @@ public:
|
||||
|
||||
/** @brief allocate limit as new top(parent)**/
|
||||
int allocate_limit_as_top(ObLogicalOperator*& old_top, ObRawExpr* limit_expr, ObRawExpr* offset_expr,
|
||||
ObRawExpr* percent_expr, common::ObIArray<OrderItem>& expect_ordering, const bool has_union_child,
|
||||
const bool is_calc_found_rows, const bool is_top_limit, const bool is_fetch_with_ties);
|
||||
ObRawExpr* percent_expr, common::ObIArray<OrderItem>& expect_ordering, const bool is_calc_found_rows,
|
||||
const bool is_top_limit, const bool is_fetch_with_ties);
|
||||
|
||||
/**
|
||||
* Plan tree traversing(both top-down and bottom-up)
|
||||
|
@ -2014,12 +2014,9 @@ int ObLogicalOperator::set_sort_topn()
|
||||
OB_ISNULL(session = optm_ctx->get_session_info())) {
|
||||
LOG_WARN("get unexpected null", K(get_plan()), K(optm_ctx), K(session), K(ret));
|
||||
} else if (LOG_LIMIT == get_type()) {
|
||||
bool need_calc = false;
|
||||
ObLogLimit* op_limit = static_cast<ObLogLimit*>(this);
|
||||
is_fetch_with_ties = op_limit->is_fetch_with_ties();
|
||||
if (OB_FAIL(op_limit->need_calc_found_rows(need_calc))) {
|
||||
LOG_WARN("call need_calc_found_rows failed", K(ret));
|
||||
} else if (need_calc) {
|
||||
if (op_limit->get_is_calc_found_rows()) {
|
||||
/*do nothing*/
|
||||
} else {
|
||||
limit_count_expr = op_limit->get_limit_count();
|
||||
|
@ -359,7 +359,7 @@ int ObSelectLogPlan::candi_allocate_distinct()
|
||||
} else if (OB_ISNULL(limit_expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("limit_expr is null", K(ret));
|
||||
} else if (OB_FAIL(candi_allocate_limit(limit_expr, NULL, NULL, dummy_order_items, false, false, false, false))) {
|
||||
} else if (OB_FAIL(candi_allocate_limit(limit_expr, NULL, NULL, dummy_order_items, false, false, false))) {
|
||||
LOG_WARN("failed to allocate limit operator", K(ret));
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
|
@ -277,11 +277,9 @@ int ObTransformSemiToInner::check_semi_join_condition(ObDMLStmt& stmt, SemiInfo&
|
||||
if (OB_ISNULL(expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpect null expr", K(ret));
|
||||
} else if (left_table_set.is_superset(expr->get_relation_ids())) {
|
||||
// do nothing for left filters
|
||||
} else if (right_table_set.is_superset(expr->get_relation_ids())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected semi condition", K(ret), K(*expr));
|
||||
} else if (left_table_set.is_superset(expr->get_relation_ids()) ||
|
||||
right_table_set.is_superset(expr->get_relation_ids())) {
|
||||
// do nothing for left/right filters
|
||||
} else if (T_OP_EQ != expr->get_expr_type()) {
|
||||
is_all_equal_cond = false;
|
||||
} else if (OB_ISNULL(left = expr->get_param_expr(0)) || OB_ISNULL(right = expr->get_param_expr(1))) {
|
||||
|
@ -607,7 +607,7 @@ SQL: select c1 from t1 union all select c1 from t2 order by c1 limit 1;
|
||||
|ID|OPERATOR |NAME|EST. ROWS|COST|
|
||||
--------------------------------------
|
||||
|0 |LIMIT | |1 |74 |
|
||||
|1 | SORT | |1 |74 |
|
||||
|1 | TOP-N SORT | |1 |74 |
|
||||
|2 | UNION ALL | |2 |73 |
|
||||
|3 | TABLE SCAN|t1 |1 |36 |
|
||||
|4 | TABLE SCAN|t2 |1 |36 |
|
||||
@ -616,7 +616,7 @@ SQL: select c1 from t1 union all select c1 from t2 order by c1 limit 1;
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([UNION([1])]), filter(nil), limit(1), offset(nil)
|
||||
1 - output([UNION([1])]), filter(nil), sort_keys([UNION([1]), ASC])
|
||||
1 - output([UNION([1])]), filter(nil), sort_keys([UNION([1]), ASC]), topn(1)
|
||||
2 - output([UNION([1])]), filter(nil)
|
||||
3 - output([t1.c1]), filter(nil),
|
||||
access([t1.c1]), partitions(p0),
|
||||
@ -631,7 +631,7 @@ SQL: select c2 from t2 union all select c2 from t3 order by c2 limit 1;
|
||||
|ID|OPERATOR |NAME|EST. ROWS|COST|
|
||||
----------------------------------------
|
||||
|0 |LIMIT | |1 |228 |
|
||||
|1 | SORT | |1 |228 |
|
||||
|1 | TOP-N SORT | |1 |228 |
|
||||
|2 | UNION ALL | |2 |227 |
|
||||
|3 | LIMIT | |1 |113 |
|
||||
|4 | TOP-N SORT | |1 |113 |
|
||||
@ -644,7 +644,7 @@ SQL: select c2 from t2 union all select c2 from t3 order by c2 limit 1;
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([UNION([1])]), filter(nil), limit(1), offset(nil)
|
||||
1 - output([UNION([1])]), filter(nil), sort_keys([UNION([1]), ASC])
|
||||
1 - output([UNION([1])]), filter(nil), sort_keys([UNION([1]), ASC]), topn(1)
|
||||
2 - output([UNION([1])]), filter(nil)
|
||||
3 - output([t2.c2]), filter(nil), limit(1), offset(nil)
|
||||
4 - output([t2.c2]), filter(nil), sort_keys([t2.c2, ASC]), topn(1)
|
||||
@ -705,7 +705,7 @@ SQL: (select c2, c3 from t2) union all (select c2, c3 from t3 order by c3) order
|
||||
|ID|OPERATOR |NAME|EST. ROWS|COST|
|
||||
----------------------------------------
|
||||
|0 |LIMIT | |1 |308 |
|
||||
|1 | SORT | |1 |307 |
|
||||
|1 | TOP-N SORT | |1 |307 |
|
||||
|2 | UNION ALL | |2 |306 |
|
||||
|3 | LIMIT | |1 |153 |
|
||||
|4 | TOP-N SORT | |1 |153 |
|
||||
@ -718,7 +718,7 @@ SQL: (select c2, c3 from t2) union all (select c2, c3 from t3 order by c3) order
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([UNION([1])], [UNION([2])]), filter(nil), limit(1), offset(nil)
|
||||
1 - output([UNION([1])], [UNION([2])]), filter(nil), sort_keys([UNION([1]), ASC])
|
||||
1 - output([UNION([1])], [UNION([2])]), filter(nil), sort_keys([UNION([1]), ASC]), topn(1)
|
||||
2 - output([UNION([1])], [UNION([2])]), filter(nil)
|
||||
3 - output([t2.c2], [t2.c3]), filter(nil), limit(1), offset(nil)
|
||||
4 - output([t2.c2], [t2.c3]), filter(nil), sort_keys([t2.c2, ASC]), topn(1)
|
||||
|
@ -179,7 +179,7 @@ SQL: select c1 from t1 union all select c2 from t2 order by c1 limit 2;
|
||||
|ID|OPERATOR |NAME|EST. ROWS|COST|
|
||||
----------------------------------------
|
||||
|0 |LIMIT | |2 |161 |
|
||||
|1 | SORT | |2 |161 |
|
||||
|1 | TOP-N SORT | |2 |161 |
|
||||
|2 | UNION ALL | |4 |159 |
|
||||
|3 | TABLE SCAN |t1 |2 |37 |
|
||||
|4 | LIMIT | |2 |122 |
|
||||
@ -190,7 +190,7 @@ SQL: select c1 from t1 union all select c2 from t2 order by c1 limit 2;
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([UNION([1])]), filter(nil), limit(2), offset(nil)
|
||||
1 - output([UNION([1])]), filter(nil), sort_keys([UNION([1]), ASC])
|
||||
1 - output([UNION([1])]), filter(nil), sort_keys([UNION([1]), ASC]), topn(2)
|
||||
2 - output([UNION([1])]), filter(nil)
|
||||
3 - output([t1.c1]), filter(nil),
|
||||
access([t1.c1]), partitions(p0),
|
||||
@ -206,7 +206,7 @@ SQL: select c1, c2 from t1 order by c2 union all select c1, c2 from t2 order by
|
||||
|ID|OPERATOR |NAME|EST. ROWS|COST|
|
||||
--------------------------------------
|
||||
|0 |LIMIT | |2 |77 |
|
||||
|1 | SORT | |2 |76 |
|
||||
|1 | TOP-N SORT | |2 |76 |
|
||||
|2 | UNION ALL | |4 |74 |
|
||||
|3 | TABLE SCAN|t1 |2 |37 |
|
||||
|4 | TABLE SCAN|t2 |2 |37 |
|
||||
@ -215,7 +215,7 @@ SQL: select c1, c2 from t1 order by c2 union all select c1, c2 from t2 order by
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([UNION([1])], [UNION([2])]), filter(nil), limit(2), offset(nil)
|
||||
1 - output([UNION([1])], [UNION([2])]), filter(nil), sort_keys([UNION([1]), ASC])
|
||||
1 - output([UNION([1])], [UNION([2])]), filter(nil), sort_keys([UNION([1]), ASC]), topn(2)
|
||||
2 - output([UNION([1])], [UNION([2])]), filter(nil)
|
||||
3 - output([t1.c1], [t1.c2]), filter(nil),
|
||||
access([t1.c1], [t1.c2]), partitions(p0),
|
||||
@ -230,7 +230,7 @@ SQL: select c1, c2 from t1 limit 5 union all select c1, c2 from t2 order by c1 l
|
||||
|ID|OPERATOR |NAME|EST. ROWS|COST|
|
||||
--------------------------------------
|
||||
|0 |LIMIT | |2 |79 |
|
||||
|1 | SORT | |2 |79 |
|
||||
|1 | TOP-N SORT | |2 |79 |
|
||||
|2 | UNION ALL | |7 |76 |
|
||||
|3 | TABLE SCAN|t1 |5 |37 |
|
||||
|4 | TABLE SCAN|t2 |2 |37 |
|
||||
@ -239,7 +239,7 @@ SQL: select c1, c2 from t1 limit 5 union all select c1, c2 from t2 order by c1 l
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([UNION([1])], [UNION([2])]), filter(nil), limit(2), offset(nil)
|
||||
1 - output([UNION([1])], [UNION([2])]), filter(nil), sort_keys([UNION([1]), ASC])
|
||||
1 - output([UNION([1])], [UNION([2])]), filter(nil), sort_keys([UNION([1]), ASC]), topn(2)
|
||||
2 - output([UNION([1])], [UNION([2])]), filter(nil)
|
||||
3 - output([t1.c1], [t1.c2]), filter(nil),
|
||||
access([t1.c1], [t1.c2]), partitions(p0),
|
||||
|
Loading…
x
Reference in New Issue
Block a user