1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-18 17:42:25 +03:00

Consider syntactic form when disambiguating function vs column reference.

Postgres has traditionally considered the syntactic forms f(x) and x.f
to be equivalent, allowing tricks such as writing a function and then
using it as though it were a computed-on-demand column.  However, our
behavior when both interpretations are feasible left something to be
desired: we always chose the column interpretation.  This could lead
to very surprising results, as in a recent bug report from Neil Conway.
It also created a dump-and-reload hazard, since what was a function
call in a dumped view could get interpreted as a column reference
at reload, if a matching column name had been added to the underlying
table since the view was created.

What seems better, in ambiguous situations, is to prefer the choice
matching the syntactic form of the reference.  This seems much less
astonishing in general, and it fixes the dump/reload hazard.

Although this could be called a bug fix, there have been few complaints
and there's some small risk of breaking applications that depend on the
old behavior, so no back-patch.  It does seem reasonable to slip it
into v11, though.

Discussion: https://postgr.es/m/CAOW5sYa3Wp7KozCuzjOdw6PiOYPi6D=VvRybtH2S=2C0SVmRmA@mail.gmail.com
This commit is contained in:
Tom Lane
2018-06-18 11:39:33 -04:00
parent 4c8156d871
commit b97a3465d7
4 changed files with 148 additions and 50 deletions

View File

@ -797,6 +797,50 @@ select (row('Jim', 'Beam')).text; -- error
ERROR: could not identify column "text" in record data type
LINE 1: select (row('Jim', 'Beam')).text;
^
--
-- Check the equivalence of functional and column notation
--
insert into fullname values ('Joe', 'Blow');
select f.last from fullname f;
last
------
Blow
(1 row)
select last(f) from fullname f;
last
------
Blow
(1 row)
create function longname(fullname) returns text language sql
as $$select $1.first || ' ' || $1.last$$;
select f.longname from fullname f;
longname
----------
Joe Blow
(1 row)
select longname(f) from fullname f;
longname
----------
Joe Blow
(1 row)
-- Starting in v11, the notational form does matter if there's ambiguity
alter table fullname add column longname text;
select f.longname from fullname f;
longname
----------
(1 row)
select longname(f) from fullname f;
longname
----------
Joe Blow
(1 row)
--
-- Test that composite values are seen to have the correct column names
-- (bug #11210 and other reports)

View File

@ -345,6 +345,26 @@ select (row('Jim', 'Beam'))::text;
select text(row('Jim', 'Beam')); -- error
select (row('Jim', 'Beam')).text; -- error
--
-- Check the equivalence of functional and column notation
--
insert into fullname values ('Joe', 'Blow');
select f.last from fullname f;
select last(f) from fullname f;
create function longname(fullname) returns text language sql
as $$select $1.first || ' ' || $1.last$$;
select f.longname from fullname f;
select longname(f) from fullname f;
-- Starting in v11, the notational form does matter if there's ambiguity
alter table fullname add column longname text;
select f.longname from fullname f;
select longname(f) from fullname f;
--
-- Test that composite values are seen to have the correct column names
-- (bug #11210 and other reports)