Thread: Postgres Incompatibility
Hi Experts
I noticed this problem when creating a backup on Postgres 13 and restoring it on Postgres 15.
CREATE FUNCTION sync.show_pg_subscription1() RETURNS SETOF pg_subscription
LANGUAGE sql
AS $$
SELECT * from pg_subscription;
$$;
The Postgres backup creates the view syntax with " FROM sync.show_pg_subscription1() show_pg_subscription1(oid, subdbid, subname, subowner, subenabled, subconninfo, subslotname, subsynccommit, subpublications);" The original syntax just had FROM sync.show_pg_subscription1() .
CREATE OR REPLACE VIEW sync.pg_subscription_view1
AS
SELECT show_pg_subscription1.oid,
show_pg_subscription1.subdbid,
show_pg_subscription1.subname,
show_pg_subscription1.subowner,
show_pg_subscription1.subenabled,
show_pg_subscription1.subconninfo,
show_pg_subscription1.subslotname,
show_pg_subscription1.subsynccommit,
show_pg_subscription1.subpublications
FROM sync.show_pg_subscription1() show_pg_subscription1(oid, subdbid, subname, subowner, subenabled, subconninfo, subslotname, subsynccommit, subpublications);
We get an error:
ERROR: column reference "subconninfo" is ambiguous LINE 8: show_pg_subscription1.subconninfo,
If we remove the part generated by Postgres backup " show_pg_subscription1(oid, subdbid, subname, subowner, subenabled, subconninfo, subslotname, subsynccommit, subpublications);" it works.
What can be done so backups will be able to restore correctly? I have a not so elegant solution, but I hope to hear a better solution than creating additional view:
create view abc as
SELECT
oid,
subdbid,
subname,
subowner,
subenabled,
subconninfo,
subslotname,
subsynccommit,
subpublications
from pg_subscription p;
CREATE FUNCTION sync.show_pg_subscription1() RETURNS SETOF abc
LANGUAGE sql
AS $$
SELECT * from abc;
$$;
SELECT show_pg_subscription1.oid,
show_pg_subscription1.subdbid,
show_pg_subscription1.subname,
show_pg_subscription1.subowner,
show_pg_subscription1.subenabled,
show_pg_subscription1.subconninfo,
show_pg_subscription1.subslotname,
show_pg_subscription1.subsynccommit,
show_pg_subscription1.subpublications
FROM sync.show_pg_subscription1() show_pg_subscription1(oid, subdbid, subname, subowner, subenabled, subconninfo, subslotname, subsynccommit, subpublications);
This works also with the additional part generated by Postgres backup
Thanks!
Avi Weinberg <AviW@gilat.com> writes: > I noticed this problem when creating a backup on Postgres 13 and restoring it on Postgres 15. > CREATE FUNCTION sync.show_pg_subscription1() RETURNS SETOF pg_subscription > LANGUAGE sql > AS $$ > SELECT * from pg_subscription; > $$; > The Postgres backup creates the view syntax with " FROM sync.show_pg_subscription1() show_pg_subscription1(oid, subdbid,subname, subowner, subenabled, subconninfo, subslotname, subsynccommit, subpublications);" Yeah. This is intentional: if we don't decompile function calls that way, then other cases break. I'd say the fundamental problem here is that you used the antipattern "SELECT * FROM ...", rather than listing out the columns you want explicitly. Even introductory SQL textbooks warn against doing that in long-lived code. It would actually still have worked if you'd not bothered with the intermediate function, which seems to be adding nothing except execution cost and complication. If you'd just done CREATE VIEW sync.pg_subscription_view1 AS SELECT * FROM pg_subscription; then this would have decompiled as selecting specific columns from pg_subscription, and it would have been quite safe against column additions or reordering in pg_subscription. Having said that, we do reserve the right to actually change existing columns in system catalogs. So you simply cannot expect that code that looks at system catalogs is never going to need to be touched when doing a major version upgrade. regards, tom lane