diff --git a/src/sql/optimizer/ob_log_table_scan.cpp b/src/sql/optimizer/ob_log_table_scan.cpp index 3c9b9fc78a..0f0b48af9b 100644 --- a/src/sql/optimizer/ob_log_table_scan.cpp +++ b/src/sql/optimizer/ob_log_table_scan.cpp @@ -577,39 +577,21 @@ int ObLogTableScan::replace_gen_col_op_exprs(ObRawExprReplacer &replacer) int ObLogTableScan::replace_index_back_pushdown_filters(ObRawExprReplacer &replacer) { int ret = OB_SUCCESS; - ObIArray &filters = get_filter_exprs(); - const auto &flags = get_filter_before_index_flags(); - if (get_contains_fake_cte() || is_virtual_table(get_ref_table_id())) { - // nonpushdown need replace. - if (OB_FAIL(replace_exprs_action(replacer, filters))) { - LOG_WARN("failed to replace agg expr", K(ret)); - } - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < filters.count(); ++i) { - if (filters.at(i)->has_flag(CNT_PL_UDF)) { - // nonpushdown need replace. - if (OB_FAIL(replace_expr_action(replacer, filters.at(i)))) { - LOG_WARN("failed to replace agg expr", K(ret)); - } - } else if (!get_index_back()) { - // scan_pushdown no need replace. - } else if (flags.empty() || i >= flags.count()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("filter before index flag is invalid", K(ret), K(i), K(flags), K(filters)); - } else if (flags.at(i)) { - if (get_index_back() && get_is_index_global() && filters.at(i)->has_flag(CNT_SUB_QUERY)) { - // lookup_pushdown need replace. - if (OB_FAIL(replace_expr_action(replacer, filters.at(i)))) { - LOG_WARN("failed to replace agg expr", K(ret)); - } - } else { - // scan_pushdown no need replace. - } - } else if (OB_FAIL(replace_expr_action(replacer, filters.at(i)))) { - LOG_WARN("failed to replace agg expr", K(ret)); - } - } - } + ObArray non_pushdown_expr; + ObArray scan_pushdown_filters; + ObArray lookup_pushdown_filters; + if (OB_UNLIKELY(!get_index_back())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("go wrong way", K(ret)); + } else if (OB_FAIL(extract_pushdown_filters(non_pushdown_expr, + scan_pushdown_filters, + lookup_pushdown_filters))) { + LOG_WARN("extract pushdown filters failed", K(ret)); + } else if (OB_FAIL(replace_exprs_action(replacer, non_pushdown_expr))) { + LOG_WARN("failed to replace non pushdown expr", K(ret)); + } else if (OB_FAIL(replace_exprs_action(replacer, lookup_pushdown_filters))) { + LOG_WARN("failed to replace lookup pushdown expr", K(ret)); + } else { /* do nothing */ } return ret; } diff --git a/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/table_scan.result b/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/table_scan.result index 5441ff4701..a53d1fa0a8 100644 --- a/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/table_scan.result +++ b/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/table_scan.result @@ -2,6 +2,7 @@ result_format: 4 explain_protocol: 0 drop table if exists t1; +drop table if exists t2; create table t1 (c1 number, c2 number, c3 char(20), c4 varchar(20), primary key(c1, c2), index i1 (c2)); insert into t1 (c1, c2, c3, c4) values (1, 2, 'a', 'b'); @@ -313,3 +314,45 @@ select /*+index(t1 idx)*/ c1, c2, c3 from t1 where c3 != 1 limit 2; +----+------+------+ drop table t1; +CREATE TABLE t1 (c1 bigint, c2 bigint); +CREATE TABLE t2 (c1 NUMERIC(64,19), c2 DECIMAL(64,16), c3 INTEGER(127), c4 NUMERIC(64,18), c5 DECIMAL(64,0) GENERATED always AS (c3 + c4), c6 int); +CREATE UNIQUE INDEX idx1 ON t2(c2, c1, c5) GLOBAL ; +EXPLAIN select /*+use_nl(t1 t2) parallel(2) */t1.c1, t2.c6 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c2 AND t1.c2 <= t2.c5; +Query Plan +====================================================================== +|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)| +---------------------------------------------------------------------- +|0 |PX COORDINATOR | |1 |21 | +|1 |└─EXCHANGE OUT DISTR |:EX10000|1 |21 | +|2 | └─NESTED-LOOP OUTER JOIN | |1 |21 | +|3 | ├─PX BLOCK ITERATOR | |1 |2 | +|4 | │ └─TABLE FULL SCAN |t1 |1 |2 | +|5 | └─DISTRIBUTED TABLE RANGE SCAN|t2(idx1)|1 |19 | +====================================================================== +Outputs & filters: +------------------------------------- + 0 - output([INTERNAL_FUNCTION(t1.c1, t2.c6)]), filter(nil), rowset=16 + 1 - output([INTERNAL_FUNCTION(t1.c1, t2.c6)]), filter(nil), rowset=16 + dop=2 + 2 - output([t1.c1], [t2.c6]), filter(nil), rowset=16 + conds(nil), nl_params_([t1.c1(:0)], [t1.c2(:1)]), use_batch=true + 3 - output([t1.c1], [t1.c2]), filter(nil), rowset=16 + 4 - output([t1.c1], [t1.c2]), filter(nil), rowset=16 + access([t1.c1], [t1.c2]), partitions(p0) + is_index_back=false, is_global_index=false, + range_key([t1.__pk_increment]), range(MIN ; MAX)always true + 5 - output([t2.c6]), filter([cast(:1, DECIMAL_INT(64, 0)) <= column_conv(DECIMAL_INT,PS:(64,0),NULL,cast(cast(t2.c3, DECIMAL_INT(81, 18)) + cast(t2.c4, + DECIMAL_INT(81, 18)), DECIMAL_INT(64, 0)))]), rowset=16 + access([GROUP_ID], [t2.__pk_increment], [t2.c3], [t2.c4], [t2.c6]), partitions(p0) + is_index_back=true, is_global_index=false, filter_before_indexback[true], + range_key([t2.c2], [t2.c1], [t2.c5], [t2.shadow_pk_0]), range(MIN ; MAX), + range_cond([cast(:0, DECIMAL_INT(64, 16)) = t2.c2]) +select /*+use_nl(t1 t2) parallel(2) */t1.c1, t2.c6 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c2 AND t1.c2 <= t2.c5; ++------+------+ +| c1 | c6 | ++------+------+ ++------+------+ + +drop table t1; +drop table t2; + diff --git a/tools/deploy/mysql_test/test_suite/static_engine/t/table_scan.test b/tools/deploy/mysql_test/test_suite/static_engine/t/table_scan.test index e1ffa48dbf..d088212cfb 100644 --- a/tools/deploy/mysql_test/test_suite/static_engine/t/table_scan.test +++ b/tools/deploy/mysql_test/test_suite/static_engine/t/table_scan.test @@ -10,6 +10,7 @@ connection default; --disable_warnings drop table if exists t1; +drop table if exists t2; --enable_warnings create table t1 (c1 number, c2 number, c3 char(20), c4 varchar(20), primary key(c1, c2), index i1 (c2)); @@ -70,5 +71,13 @@ select /*+index(t1 idx)*/ c1, c2, c3 from t1 where c3 != 1 limit 2; drop table t1; --enable_warnings +CREATE TABLE t1 (c1 bigint, c2 bigint); +CREATE TABLE t2 (c1 NUMERIC(64,19), c2 DECIMAL(64,16), c3 INTEGER(127), c4 NUMERIC(64,18), c5 DECIMAL(64,0) GENERATED always AS (c3 + c4), c6 int); +CREATE UNIQUE INDEX idx1 ON t2(c2, c1, c5) GLOBAL ; +select /*+use_nl(t1 t2) parallel(2) */t1.c1, t2.c6 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c2 AND t1.c2 <= t2.c5; + +drop table t1; +drop table t2; + connection syscon; --sleep 2