diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2023-03-07 18:21:37 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2023-03-07 18:21:37 -0500 |
commit | 9f1e51b5967345afc42efb6c146043b5bcd91679 (patch) | |
tree | 7d5bc7b34c9f80cc87a1cd6df0728e2a014f4ba7 /src/backend/parser/parse_relation.c | |
parent | 1e05ea51d327635ce56caab56cc47e70716e081f (diff) | |
download | postgresql-9f1e51b5967345afc42efb6c146043b5bcd91679.tar.gz postgresql-9f1e51b5967345afc42efb6c146043b5bcd91679.zip |
Fix more bugs caused by adding columns to the end of a view.
If a view is defined atop another view, and then CREATE OR REPLACE
VIEW is used to add columns to the lower view, then when the upper
view's referencing RTE is expanded by ApplyRetrieveRule we will have
a subquery RTE with fewer eref->colnames than output columns. This
confuses various code that assumes those lists are always in sync,
as they are in plain parser output.
We have seen such problems before (cf commit d5b760ecb), and now
I think the time has come to do what was speculated about in that
commit: let's make ApplyRetrieveRule synthesize some column names to
preserve the invariant that holds in parser output. Otherwise we'll
be chasing this class of bugs indefinitely. Moreover, it appears from
testing that this actually gives us better results in the test case
d5b760ecb added, and likely in other corner cases that we lack
coverage for.
In HEAD, I replaced d5b760ecb's hack to make expandRTE exit early with
an elog(ERROR) call, since the case is now presumably unreachable.
But it seems like changing that in back branches would bring more risk
than benefit, so there I just updated the comment.
Per bug #17811 from Alexander Lakhin. Back-patch to all supported
branches.
Discussion: https://postgr.es/m/17811-d31686b78f0dffc9@postgresql.org
Diffstat (limited to 'src/backend/parser/parse_relation.c')
-rw-r--r-- | src/backend/parser/parse_relation.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 713ec0e521d..4193a03ebba 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -2658,12 +2658,17 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up, Assert(varattno == te->resno); /* - * In scenarios where columns have been added to a view - * since the outer query was originally parsed, there can - * be more items in the subquery tlist than the outer - * query expects. We should ignore such extra column(s) - * --- compare the behavior for composite-returning - * functions, in the RTE_FUNCTION case below. + * In a just-parsed subquery RTE, rte->eref->colnames + * should always have exactly as many entries as the + * subquery has non-junk output columns. However, if the + * subquery RTE was created by expansion of a view, + * perhaps the subquery tlist could now have more entries + * than existed when the outer query was parsed. Such + * cases should now be prevented because ApplyRetrieveRule + * will extend the colnames list to match. But out of + * caution, we'll keep the code like this in the back + * branches: just ignore any columns that lack colnames + * entries. */ if (!aliasp_item) break; |