diff options
| author | David Rowley <drowley@postgresql.org> | 2022-05-27 10:37:58 +1200 |
|---|---|---|
| committer | David Rowley <drowley@postgresql.org> | 2022-05-27 10:37:58 +1200 |
| commit | 3e9abd2eb1b1f6863250f060290f514f30ce8044 (patch) | |
| tree | 12e997b82b3f2ea3079b41f618c8d35792c3df5c /src/test | |
| parent | 2b65de7fc296bb5060c8d4ae8cb680f71364fbe0 (diff) | |
Teach remove_unused_subquery_outputs about window run conditions
9d9c02ccd added code to allow the executor to take shortcuts when quals
on monotonic window functions guaranteed that once the qual became false
it could never become true again. When possible, baserestrictinfo quals
are converted to become these quals, which we call run conditions.
Unfortunately, in 9d9c02ccd, I forgot to update
remove_unused_subquery_outputs to teach it about these run conditions.
This could cause a WindowFunc column which was unused in the target list
but referenced by an upper-level WHERE clause to be removed from the
subquery when the qual in the WHERE clause was converted into a window run
condition. Because of this, the entire WindowClause would be removed from
the query resulting in additional rows making it into the resultset when
they should have been filtered out by the WHERE clause.
Here we fix this by recording which target list items in the subquery have
run conditions. That gets passed along to remove_unused_subquery_outputs
to tell it not to remove these items from the target list.
Bug: #17495
Reported-by: Jeremy Evans
Reviewed-by: Richard Guo
Discussion: https://postgr.es/m/17495-7ffe2fa0b261b9fa@postgresql.org
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/regress/expected/window.out | 19 | ||||
| -rw-r--r-- | src/test/regress/sql/window.sql | 10 |
2 files changed, 29 insertions, 0 deletions
diff --git a/src/test/regress/expected/window.out b/src/test/regress/expected/window.out index d78b4c463cf..433a0bb0259 100644 --- a/src/test/regress/expected/window.out +++ b/src/test/regress/expected/window.out @@ -3589,6 +3589,25 @@ WHERE rn < 3; 3 | sales | 2 (6 rows) +-- ensure that "unused" subquery columns are not removed when the column only +-- exists in the run condition +EXPLAIN (COSTS OFF) +SELECT empno, depname FROM + (SELECT empno, + depname, + row_number() OVER (PARTITION BY depname ORDER BY empno) rn + FROM empsalary) emp +WHERE rn < 3; + QUERY PLAN +------------------------------------------------------------ + Subquery Scan on emp + -> WindowAgg + Run Condition: (row_number() OVER (?) < 3) + -> Sort + Sort Key: empsalary.depname, empsalary.empno + -> Seq Scan on empsalary +(6 rows) + -- likewise with count(empno) instead of row_number() EXPLAIN (COSTS OFF) SELECT * FROM diff --git a/src/test/regress/sql/window.sql b/src/test/regress/sql/window.sql index 967b9413de6..a504e46e403 100644 --- a/src/test/regress/sql/window.sql +++ b/src/test/regress/sql/window.sql @@ -1121,6 +1121,16 @@ SELECT * FROM FROM empsalary) emp WHERE rn < 3; +-- ensure that "unused" subquery columns are not removed when the column only +-- exists in the run condition +EXPLAIN (COSTS OFF) +SELECT empno, depname FROM + (SELECT empno, + depname, + row_number() OVER (PARTITION BY depname ORDER BY empno) rn + FROM empsalary) emp +WHERE rn < 3; + -- likewise with count(empno) instead of row_number() EXPLAIN (COSTS OFF) SELECT * FROM |
