This is an automated email from the ASF dual-hosted git repository. laszlog pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/impala.git
commit 88275f327fb2b52db13d1ffa1db8fafd08875941 Author: Minghui Zhu <[email protected]> AuthorDate: Wed Apr 19 11:54:25 2023 +0000 IMPALA-12051: Propagate analytic tuple predicates of outer-joined InlineView In some cases, direct pushing down predicates that reference analytic tuple into inline view leads to incorrect query results. While pushing down analytic predicates (e.g. row_number() < 10), we should also divide them into two groups. Some of them can be migrated into the view so are removed in the current scope. Some of them can be copied into the view but still need to be evaluated in the current scope as demonstrated with the following query. The bug is due to we migrate all of them into the view. WITH detail_measure AS ( SELECT * FROM ( VALUES ( 1 AS `isqbiuar`, 1 AS `bgsfrbun`, 1 AS `result_type`, 1 AS `bjuzzevg` ), (2, 2, 2, 2) ) a ), order_measure_sql0 AS ( SELECT row_number() OVER ( ORDER BY row_number_0 DESC NULLS LAST, isqbiuar ASC NULLS LAST ) AS `row_number_0`, `isqbiuar` FROM ( VALUES (1 AS `row_number_0`, 1 AS `isqbiuar`), (2, 2) ) b ) SELECT detail_measure.`isqbiuar` AS `isqbiuar`, detail_measure.`bgsfrbun` AS `bgsfrbun`, detail_measure.`result_type` AS `result_type`, detail_measure.`bjuzzevg` AS `bjuzzevg`, `row_number_0` AS `row_number_0` FROM detail_measure LEFT JOIN order_measure_sql0 ON order_measure_sql0.isqbiuar = detail_measure.isqbiuar WHERE row_number_0 BETWEEN 1 AND 1 ORDER BY `row_number_0` ASC NULLS LAST, `bgsfrbun` ASC NULLS LAST The current incorrect result is: +----------+----------+-------------+----------+--------------+ | isqbiuar | bgsfrbun | result_type | bjuzzevg | row_number_0 | +----------+----------+-------------+----------+--------------+ | 2 | 2 | 2 | 2 | 1 | | 1 | 1 | 1 | 1 | NULL | +----------+----------+-------------+----------+--------------+ The correct result is: +----------+----------+-------------+----------+--------------+ | isqbiuar | bgsfrbun | result_type | bjuzzevg | row_number_0 | +----------+----------+-------------+----------+--------------+ | 2 | 2 | 2 | 2 | 1 | +----------+----------+-------------+----------+--------------+ In the plan, the analysis predicate is pushed down to the TOP-N node, but not in the HASH JOIN node, which leads to incorrect results. ... 05:HASH JOIN [RIGHT OUTER JOIN] | hash predicates: isqbiuar = isqbiuar | row-size=14B cardinality=2 ... 02:TOP-N [LIMIT=1] | order by: row_number_0 DESC NULLS LAST, isqbiuar ASC NULLS LAST | source expr: row_number() <= CAST(1 AS BIGINT) | row-size=2B cardinality=1 ... The HASH JOIN node shoud be: 05:HASH JOIN [RIGHT OUTER JOIN] | hash predicates: isqbiuar = isqbiuar | other predicates: row_number() <= 1, row_number() >= 1 | row-size=14B cardinality=2 Tests: * Add plan tests in analytic-rank-pushdown.test * Add e2e tests in analytic-fns.test Change-Id: If6c209b2a64bad37d893ba8b520342bf1f9a7513 Reviewed-on: http://gerrit.cloudera.org:8080/19768 Reviewed-by: Impala Public Jenkins <[email protected]> Tested-by: Impala Public Jenkins <[email protected]> --- .../apache/impala/planner/SingleNodePlanner.java | 66 ++-- .../PlannerTest/analytic-rank-pushdown.test | 434 +++++++++++++++++++++ .../queries/QueryTest/analytic-fns.test | 84 ++++ 3 files changed, 553 insertions(+), 31 deletions(-) diff --git a/fe/src/main/java/org/apache/impala/planner/SingleNodePlanner.java b/fe/src/main/java/org/apache/impala/planner/SingleNodePlanner.java index 71c7af2e5..9437fddf6 100644 --- a/fe/src/main/java/org/apache/impala/planner/SingleNodePlanner.java +++ b/fe/src/main/java/org/apache/impala/planner/SingleNodePlanner.java @@ -1308,9 +1308,8 @@ public class SingleNodePlanner { * inline view, add it to 'evalAfterJoinPreds'. */ private void getConjunctsToInlineView(final Analyzer analyzer, final String alias, - final List<TupleId> tupleIds, List<Expr> evalInInlineViewPreds, - List<Expr> evalAfterJoinPreds) { - List<Expr> unassignedConjuncts = analyzer.getUnassignedConjuncts(tupleIds, true); + final List<TupleId> tupleIds, final List<Expr> unassignedConjuncts, + List<Expr> evalInInlineViewPreds, List<Expr> evalAfterJoinPreds) { for (Expr e: unassignedConjuncts) { if (!e.isBoundByTupleIds(tupleIds)) continue; List<TupleId> tids = new ArrayList<>(); @@ -1391,37 +1390,14 @@ public class SingleNodePlanner { List<Expr> analyticPreds = findAnalyticConjunctsToMigrate(analyzer, inlineViewRef, unassignedConjuncts); if (analyticPreds.size() > 0) { - if (LOG.isTraceEnabled()) { - LOG.trace("Migrate analytic predicates into view " + - Expr.debugString(analyticPreds)); - } - analyzer.markConjunctsAssigned(analyticPreds); - unassignedConjuncts.removeAll(analyticPreds); - addConjunctsIntoInlineView(analyzer, inlineViewRef, analyticPreds); + migrateOrCopyConjunctsToInlineView(analyzer, inlineViewRef, tids, + analyticPreds, unassignedConjuncts); } - - // mark (fully resolve) slots referenced by unassigned conjuncts as - // materialized - List<Expr> substUnassigned = Expr.substituteList(unassignedConjuncts, - inlineViewRef.getBaseTblSmap(), analyzer, false); - analyzer.materializeSlots(substUnassigned); - return; + } else { + migrateOrCopyConjunctsToInlineView(analyzer, inlineViewRef, tids, + unassignedConjuncts, unassignedConjuncts); } - List<Expr> preds = new ArrayList<>(); - List<Expr> evalAfterJoinPreds = new ArrayList<>(); - getConjunctsToInlineView(analyzer, inlineViewRef.getExplicitAlias(), tids, preds, - evalAfterJoinPreds); - unassignedConjuncts.removeAll(preds); - // Migrate the conjuncts by marking the original ones as assigned. They will either - // be ignored if they are identity predicates (e.g. a = a), or be substituted into - // new ones (viewPredicates below). The substituted ones will be re-registered. - analyzer.markConjunctsAssigned(preds); - // Propagate the conjuncts evaluating the nullable side of outer-join. - // Don't mark them as assigned so they would be assigned at the JOIN node. - preds.addAll(evalAfterJoinPreds); - addConjunctsIntoInlineView(analyzer, inlineViewRef, preds); - // mark (fully resolve) slots referenced by remaining unassigned conjuncts as // materialized List<Expr> substUnassigned = Expr.substituteList(unassignedConjuncts, @@ -1429,6 +1405,34 @@ public class SingleNodePlanner { analyzer.materializeSlots(substUnassigned); } + /** + * Migrate or copy unassigned conjuncts into an inline view. Parameter evalPreds is + * analytic predicates when there has specific analytic, equals to unassignedConjuncts + * when there has no LIMIT/OFFSET or anylitic functions. + */ + private void migrateOrCopyConjunctsToInlineView(final Analyzer analyzer, + final InlineViewRef inlineViewRef, final List<TupleId> tids, + List<Expr> evalPreds, List<Expr> unassignedConjuncts) + throws ImpalaException { + List<Expr> evalInInlineViewPreds = new ArrayList<>(); + List<Expr> evalAfterJoinPreds = new ArrayList<>(); + getConjunctsToInlineView(analyzer, inlineViewRef.getExplicitAlias(), tids, + evalPreds, evalInInlineViewPreds, evalAfterJoinPreds); + if (LOG.isTraceEnabled()) { + LOG.trace("Assign predicates for view: migrating {}, coping {}.", + Expr.debugString(evalInInlineViewPreds), Expr.debugString(evalAfterJoinPreds)); + } + unassignedConjuncts.removeAll(evalInInlineViewPreds); + // Migrate the conjuncts by marking the original ones as assigned. They will either + // be ignored if they are identity predicates (e.g. a = a), or be substituted into + // new ones. The substituted ones will be re-registered. + analyzer.markConjunctsAssigned(evalInInlineViewPreds); + // Propagate the conjuncts evaluating the nullable side of outer-join. + // Don't mark them as assigned so they can be assigned at the JOIN node. + evalInInlineViewPreds.addAll(evalAfterJoinPreds); + addConjunctsIntoInlineView(analyzer, inlineViewRef, evalInInlineViewPreds); + } + /** * Return any conjuncts in 'conjuncts' that reference analytic exprs in 'inlineViewRef' * and can be safely migrated into 'inlineViewRef', even if diff --git a/testdata/workloads/functional-planner/queries/PlannerTest/analytic-rank-pushdown.test b/testdata/workloads/functional-planner/queries/PlannerTest/analytic-rank-pushdown.test index 8ec8bd38e..63e728efd 100644 --- a/testdata/workloads/functional-planner/queries/PlannerTest/analytic-rank-pushdown.test +++ b/testdata/workloads/functional-planner/queries/PlannerTest/analytic-rank-pushdown.test @@ -1676,3 +1676,437 @@ PLAN-ROOT SINK predicates: int_col = 1 row-size=23B cardinality=11 ==== +# Analytic predicate can only be copied to inline view. +select a.id, rnk from functional.alltypesagg a +left join ( + select id, row_number() over (order by string_col desc) as rnk + from functional.alltypesagg +) b on a.id = b.id where rnk < 100 +---- PLAN +PLAN-ROOT SINK +| +05:HASH JOIN [LEFT OUTER JOIN] +| hash predicates: a.id = id +| other predicates: row_number() < 100 +| row-size=31B cardinality=11.00K +| +|--04:SELECT +| | predicates: row_number() < 100 +| | row-size=27B cardinality=99 +| | +| 03:ANALYTIC +| | functions: row_number() +| | order by: string_col DESC +| | window: ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +| | row-size=27B cardinality=99 +| | +| 02:TOP-N [LIMIT=99] +| | order by: string_col DESC +| | source expr: row_number() < CAST(100 AS BIGINT) +| | row-size=19B cardinality=99 +| | +| 01:SCAN HDFS [functional.alltypesagg] +| HDFS partitions=11/11 files=11 size=814.73KB +| row-size=19B cardinality=11.00K +| +00:SCAN HDFS [functional.alltypesagg a] + HDFS partitions=11/11 files=11 size=814.73KB + row-size=4B cardinality=11.00K +---- DISTRIBUTEDPLAN +PLAN-ROOT SINK +| +08:EXCHANGE [UNPARTITIONED] +| +05:HASH JOIN [LEFT OUTER JOIN, BROADCAST] +| hash predicates: a.id = id +| other predicates: row_number() < 100 +| row-size=31B cardinality=11.00K +| +|--07:EXCHANGE [BROADCAST] +| | +| 04:SELECT +| | predicates: row_number() < 100 +| | row-size=27B cardinality=99 +| | +| 03:ANALYTIC +| | functions: row_number() +| | order by: string_col DESC +| | window: ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +| | row-size=27B cardinality=99 +| | +| 06:MERGING-EXCHANGE [UNPARTITIONED] +| | order by: string_col DESC +| | limit: 99 +| | +| 02:TOP-N [LIMIT=99] +| | order by: string_col DESC +| | source expr: row_number() < CAST(100 AS BIGINT) +| | row-size=19B cardinality=99 +| | +| 01:SCAN HDFS [functional.alltypesagg] +| HDFS partitions=11/11 files=11 size=814.73KB +| row-size=19B cardinality=11.00K +| +00:SCAN HDFS [functional.alltypesagg a] + HDFS partitions=11/11 files=11 size=814.73KB + row-size=4B cardinality=11.00K +==== +# Analytic predicate can only be copied when outer-joined inline view is with statement. +with b as (select id, row_number() over (order by string_col desc) as rnk + from functional.alltypesagg) +select a.id, rnk from functional.alltypesagg a +left join b on a.id = b.id where rnk < 100 +---- PLAN +PLAN-ROOT SINK +| +05:HASH JOIN [LEFT OUTER JOIN] +| hash predicates: a.id = id +| other predicates: row_number() < 100 +| row-size=31B cardinality=11.00K +| +|--04:SELECT +| | predicates: row_number() < 100 +| | row-size=27B cardinality=99 +| | +| 03:ANALYTIC +| | functions: row_number() +| | order by: string_col DESC +| | window: ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +| | row-size=27B cardinality=99 +| | +| 02:TOP-N [LIMIT=99] +| | order by: string_col DESC +| | source expr: row_number() < CAST(100 AS BIGINT) +| | row-size=19B cardinality=99 +| | +| 01:SCAN HDFS [functional.alltypesagg] +| HDFS partitions=11/11 files=11 size=814.73KB +| row-size=19B cardinality=11.00K +| +00:SCAN HDFS [functional.alltypesagg a] + HDFS partitions=11/11 files=11 size=814.73KB + row-size=4B cardinality=11.00K +---- DISTRIBUTEDPLAN +PLAN-ROOT SINK +| +08:EXCHANGE [UNPARTITIONED] +| +05:HASH JOIN [LEFT OUTER JOIN, BROADCAST] +| hash predicates: a.id = id +| other predicates: row_number() < 100 +| row-size=31B cardinality=11.00K +| +|--07:EXCHANGE [BROADCAST] +| | +| 04:SELECT +| | predicates: row_number() < 100 +| | row-size=27B cardinality=99 +| | +| 03:ANALYTIC +| | functions: row_number() +| | order by: string_col DESC +| | window: ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +| | row-size=27B cardinality=99 +| | +| 06:MERGING-EXCHANGE [UNPARTITIONED] +| | order by: string_col DESC +| | limit: 99 +| | +| 02:TOP-N [LIMIT=99] +| | order by: string_col DESC +| | source expr: row_number() < CAST(100 AS BIGINT) +| | row-size=19B cardinality=99 +| | +| 01:SCAN HDFS [functional.alltypesagg] +| HDFS partitions=11/11 files=11 size=814.73KB +| row-size=19B cardinality=11.00K +| +00:SCAN HDFS [functional.alltypesagg a] + HDFS partitions=11/11 files=11 size=814.73KB + row-size=4B cardinality=11.00K +==== +# Analytic predicate cannot be pushed down when outer-joined inline view is union statement. +select * from functional.alltypesagg a +left join +(select a.id, row_number() over (order by a.string_col desc) as rnk from functional.alltypesagg a +union select b.id, row_number() over (order by b.string_col desc) as rnk from functional.alltypesagg b) b +on a.id = b.id +where b.rnk < 100 +---- PLAN +PLAN-ROOT SINK +| +09:HASH JOIN [LEFT OUTER JOIN] +| hash predicates: a.id = id +| other predicates: rnk < 100 +| row-size=107B cardinality=11.00K +| +|--08:AGGREGATE [FINALIZE] +| | group by: id, rnk +| | having: rnk < 100 +| | row-size=12B cardinality=2.20K +| | +| 01:UNION +| | row-size=12B cardinality=22.00K +| | +| |--07:ANALYTIC +| | | functions: row_number() +| | | order by: string_col DESC +| | | window: ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +| | | row-size=27B cardinality=11.00K +| | | +| | 06:SORT +| | | order by: string_col DESC +| | | row-size=19B cardinality=11.00K +| | | +| | 05:SCAN HDFS [functional.alltypesagg b] +| | HDFS partitions=11/11 files=11 size=814.73KB +| | row-size=19B cardinality=11.00K +| | +| 04:ANALYTIC +| | functions: row_number() +| | order by: string_col DESC +| | window: ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +| | row-size=27B cardinality=11.00K +| | +| 03:SORT +| | order by: string_col DESC +| | row-size=19B cardinality=11.00K +| | +| 02:SCAN HDFS [functional.alltypesagg a] +| HDFS partitions=11/11 files=11 size=814.73KB +| row-size=19B cardinality=11.00K +| +00:SCAN HDFS [functional.alltypesagg a] + HDFS partitions=11/11 files=11 size=814.73KB + row-size=95B cardinality=11.00K +---- DISTRIBUTEDPLAN +PLAN-ROOT SINK +| +13:EXCHANGE [UNPARTITIONED] +| +09:HASH JOIN [LEFT OUTER JOIN, BROADCAST] +| hash predicates: a.id = id +| other predicates: rnk < 100 +| row-size=107B cardinality=11.00K +| +|--12:EXCHANGE [BROADCAST] +| | +| 08:AGGREGATE [FINALIZE] +| | group by: id, rnk +| | having: rnk < 100 +| | row-size=12B cardinality=2.20K +| | +| 01:UNION +| | row-size=12B cardinality=22.00K +| | +| |--07:ANALYTIC +| | | functions: row_number() +| | | order by: string_col DESC +| | | window: ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +| | | row-size=27B cardinality=11.00K +| | | +| | 11:MERGING-EXCHANGE [UNPARTITIONED] +| | | order by: string_col DESC +| | | +| | 06:SORT +| | | order by: string_col DESC +| | | row-size=19B cardinality=11.00K +| | | +| | 05:SCAN HDFS [functional.alltypesagg b] +| | HDFS partitions=11/11 files=11 size=814.73KB +| | row-size=19B cardinality=11.00K +| | +| 04:ANALYTIC +| | functions: row_number() +| | order by: string_col DESC +| | window: ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +| | row-size=27B cardinality=11.00K +| | +| 10:MERGING-EXCHANGE [UNPARTITIONED] +| | order by: string_col DESC +| | +| 03:SORT +| | order by: string_col DESC +| | row-size=19B cardinality=11.00K +| | +| 02:SCAN HDFS [functional.alltypesagg a] +| HDFS partitions=11/11 files=11 size=814.73KB +| row-size=19B cardinality=11.00K +| +00:SCAN HDFS [functional.alltypesagg a] + HDFS partitions=11/11 files=11 size=814.73KB + row-size=95B cardinality=11.00K +==== +# Analytic predicate can only be copied when inline view contains outer join. +select * from functional.alltypesagg a +left join +(select a.id, row_number() over (order by a.string_col desc) as rnk from functional.alltypesagg a +left join functional.alltypesagg b on a.id = b.id) b +on a.id = b.id +where b.rnk < 100 +---- PLAN +PLAN-ROOT SINK +| +07:HASH JOIN [LEFT OUTER JOIN] +| hash predicates: a.id = id +| other predicates: row_number() < 100 +| row-size=126B cardinality=11.00K +| +|--06:SELECT +| | predicates: row_number() < 100 +| | row-size=31B cardinality=99 +| | +| 05:ANALYTIC +| | functions: row_number() +| | order by: string_col DESC +| | window: ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +| | row-size=31B cardinality=99 +| | +| 04:TOP-N [LIMIT=99] +| | order by: string_col DESC +| | source expr: row_number() < CAST(100 AS BIGINT) +| | row-size=23B cardinality=99 +| | +| 03:HASH JOIN [LEFT OUTER JOIN] +| | hash predicates: a.id = b.id +| | row-size=23B cardinality=11.77K +| | +| |--02:SCAN HDFS [functional.alltypesagg b] +| | HDFS partitions=11/11 files=11 size=814.73KB +| | row-size=4B cardinality=11.00K +| | +| 01:SCAN HDFS [functional.alltypesagg a] +| HDFS partitions=11/11 files=11 size=814.73KB +| row-size=19B cardinality=11.00K +| +00:SCAN HDFS [functional.alltypesagg a] + HDFS partitions=11/11 files=11 size=814.73KB + row-size=95B cardinality=11.00K +---- DISTRIBUTEDPLAN +PLAN-ROOT SINK +| +12:EXCHANGE [UNPARTITIONED] +| +07:HASH JOIN [LEFT OUTER JOIN, BROADCAST] +| hash predicates: a.id = id +| other predicates: row_number() < 100 +| row-size=126B cardinality=11.00K +| +|--11:EXCHANGE [BROADCAST] +| | +| 06:SELECT +| | predicates: row_number() < 100 +| | row-size=31B cardinality=99 +| | +| 05:ANALYTIC +| | functions: row_number() +| | order by: string_col DESC +| | window: ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +| | row-size=31B cardinality=99 +| | +| 10:MERGING-EXCHANGE [UNPARTITIONED] +| | order by: string_col DESC +| | limit: 99 +| | +| 04:TOP-N [LIMIT=99] +| | order by: string_col DESC +| | source expr: row_number() < CAST(100 AS BIGINT) +| | row-size=23B cardinality=99 +| | +| 03:HASH JOIN [LEFT OUTER JOIN, PARTITIONED] +| | hash predicates: a.id = b.id +| | row-size=23B cardinality=11.77K +| | +| |--09:EXCHANGE [HASH(b.id)] +| | | +| | 02:SCAN HDFS [functional.alltypesagg b] +| | HDFS partitions=11/11 files=11 size=814.73KB +| | row-size=4B cardinality=11.00K +| | +| 08:EXCHANGE [HASH(a.id)] +| | +| 01:SCAN HDFS [functional.alltypesagg a] +| HDFS partitions=11/11 files=11 size=814.73KB +| row-size=19B cardinality=11.00K +| +00:SCAN HDFS [functional.alltypesagg a] + HDFS partitions=11/11 files=11 size=814.73KB + row-size=95B cardinality=11.00K +==== +# Analytic predicate can be pushed down when there are more predicates. +# Only the analytic predicate can be pushed down. +select * from functional.alltypesagg a +left join +(select a.id + 1 as id, row_number() over (order by a.string_col desc) as rnk, length(string_col) AS len +from functional.alltypesagg a) b +on a.id = b.id +where b.rnk < 100 and b.len = 0 and b.id > 0 +---- PLAN +PLAN-ROOT SINK +| +05:HASH JOIN [LEFT OUTER JOIN] +| hash predicates: a.id = id + 1 +| other predicates: row_number() < 100, length(string_col) = 0, id + 1 > 0 +| row-size=122B cardinality=11.00K +| +|--04:SELECT +| | predicates: row_number() < 100 +| | row-size=27B cardinality=99 +| | +| 03:ANALYTIC +| | functions: row_number() +| | order by: string_col DESC +| | window: ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +| | row-size=27B cardinality=99 +| | +| 02:TOP-N [LIMIT=99] +| | order by: string_col DESC +| | source expr: row_number() < CAST(100 AS BIGINT) +| | row-size=19B cardinality=99 +| | +| 01:SCAN HDFS [functional.alltypesagg a] +| HDFS partitions=11/11 files=11 size=814.73KB +| row-size=19B cardinality=11.00K +| +00:SCAN HDFS [functional.alltypesagg a] + HDFS partitions=11/11 files=11 size=814.73KB + row-size=95B cardinality=11.00K +---- DISTRIBUTEDPLAN +PLAN-ROOT SINK +| +08:EXCHANGE [UNPARTITIONED] +| +05:HASH JOIN [LEFT OUTER JOIN, BROADCAST] +| hash predicates: a.id = id + 1 +| other predicates: row_number() < 100, length(string_col) = 0, id + 1 > 0 +| row-size=122B cardinality=11.00K +| +|--07:EXCHANGE [BROADCAST] +| | +| 04:SELECT +| | predicates: row_number() < 100 +| | row-size=27B cardinality=99 +| | +| 03:ANALYTIC +| | functions: row_number() +| | order by: string_col DESC +| | window: ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +| | row-size=27B cardinality=99 +| | +| 06:MERGING-EXCHANGE [UNPARTITIONED] +| | order by: string_col DESC +| | limit: 99 +| | +| 02:TOP-N [LIMIT=99] +| | order by: string_col DESC +| | source expr: row_number() < CAST(100 AS BIGINT) +| | row-size=19B cardinality=99 +| | +| 01:SCAN HDFS [functional.alltypesagg a] +| HDFS partitions=11/11 files=11 size=814.73KB +| row-size=19B cardinality=11.00K +| +00:SCAN HDFS [functional.alltypesagg a] + HDFS partitions=11/11 files=11 size=814.73KB + row-size=95B cardinality=11.00K +==== diff --git a/testdata/workloads/functional-query/queries/QueryTest/analytic-fns.test b/testdata/workloads/functional-query/queries/QueryTest/analytic-fns.test index 1d2fa53a6..4c0162f2d 100644 --- a/testdata/workloads/functional-query/queries/QueryTest/analytic-fns.test +++ b/testdata/workloads/functional-query/queries/QueryTest/analytic-fns.test @@ -2230,3 +2230,87 @@ INT, STRING, BIGINT, BIGINT 85,'0',86,11 95,'0',96,12 ==== +---- QUERY +# IMPALA-11030: Propagate analytic tuple predicates of outer-joined InlineView +select a.id, b.prime_rank from alltypessmall a +left join + (select id, row_number() over (partition by string_col order by id) prime_rank + from alltypessmall) b on a.id = b.id where a.string_col = '0' and b.prime_rank <= 10 +---- TYPES +INT, BIGINT +---- RESULTS: VERIFY_IS_EQUAL_SORTED +0,1 +10,2 +20,3 +25,4 +35,5 +45,6 +50,7 +60,8 +70,9 +75,10 +==== +---- QUERY +# IMPALA-11030: Propagate analytic tuple predicates of outer-joined InlineView +with b as (select id, row_number() over (partition by string_col order by id) prime_rank + from alltypessmall) +select a.id, b.prime_rank from alltypessmall a +left join b on a.id = b.id where a.string_col = '0' and b.prime_rank <= 10 +---- TYPES +INT, BIGINT +---- RESULTS: VERIFY_IS_EQUAL_SORTED +0,1 +10,2 +20,3 +25,4 +35,5 +45,6 +50,7 +60,8 +70,9 +75,10 +==== +---- QUERY +# IMPALA-11030: Propagate analytic tuple predicates of outer-joined InlineView +select a.id, b.prime_rank from alltypessmall a +left join +(select id, row_number() over (partition by string_col order by id) prime_rank from alltypessmall a +union select id, row_number() over (partition by string_col order by id) prime_rank from alltypessmall b) b +on a.id = b.id +where a.string_col = '0' and b.prime_rank <= 10 +---- TYPES +INT, BIGINT +---- RESULTS: VERIFY_IS_EQUAL_SORTED +75,10 +35,5 +20,3 +0,1 +25,4 +10,2 +45,6 +70,9 +60,8 +50,7 +==== +---- QUERY +# IMPALA-11030: Propagate analytic tuple predicates of outer-joined InlineView +select a.id, b.prime_rank from alltypessmall a +left join +(select a.id, row_number() over (partition by a.string_col order by a.id) prime_rank from alltypessmall a +left join alltypessmall b on a.id = b.id) b +on a.id = b.id +where a.string_col = '0' and b.prime_rank <= 10 +---- TYPES +INT, BIGINT +---- RESULTS: VERIFY_IS_EQUAL_SORTED +0,1 +10,2 +20,3 +25,4 +35,5 +45,6 +50,7 +60,8 +70,9 +75,10 +====
