From: | Sergey Konoplev <gray(dot)ru(at)gmail(dot)com> |
---|---|
To: | knizhnik <knizhnik(at)garret(dot)ru> |
Cc: | Pg Hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: Polymorphic function calls |
Date: | 2013-12-30 18:07:44 |
Message-ID: | CAL_0b1tBxWy_VtDzU73M5cEc_ARECQwYDijsm2GQU+TsYmhdjw@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On Mon, Dec 30, 2013 at 2:03 AM, knizhnik <knizhnik(at)garret(dot)ru> wrote:
> On 12/30/2013 01:22 AM, Sergey Konoplev wrote:
>> On Sun, Dec 29, 2013 at 8:44 AM, knizhnik <knizhnik(at)garret(dot)ru> wrote:
>>> But passing direved_table type instead of base_table type to volume()
>>> function for record belonging to derived_table seems to be possible and
>>> not
>>> contradicting something, isn't it?
>>
>> Correct.
>>
>> Postgres chooses a function based on the passed signature. When you
>> specify base_table it will choose volume(base_table) and for
>> base_table it will be volume(derived_table) as well.
>
> I think you mean "and for derived_table it will be base_table as well".
Sure. Sorry for the typo.
> Certainly I understand the reasons of such behavior and that it will be
> difficult to introduce some other non-contradictory model...
>
> But polymorphism is one of the basic features of OO approach. Definitely
> PostgreSQL is not OODBMS. But it supports inheritance.
> And I wonder if it is possible/desirable to make an exception for function
> invocation rules for derived tables?
>
> Actually a query on table with inherited tables is implemented as join of
> several independent table traversals.
I would say it is more like union,
> But for all derived tables we restrict context to the scope of base table.
> If it is possible to leave real record type when it is passed to some
> function, we can support polymorphic calls...
>
> Will it violate some principles/rules? I am not sure...
Well, it is not implemented in Postgres.
>> FYI, there is a common practice to follow the DRY principle with
>> inheritance and polymorphic functions in Postgres. On your example it
>> might be shown like this:
>>
>> create function volume(r base_table) returns integer as $$ begin
>> return r.x*r.y;
>> end; $$ language plpgsql strict stable;
>>
>> create function volume(r derived_table) returns integer as $$ begin
>> return volume(r::base_table) *r.z;
>> end; $$ language plpgsql strict stable;
>
> I do not completely understand you here.
> Function of derived class can refere to the overridden function when it's
> result depends on result of the overridden function.
> But it is not always true, for example you can derived class Circle from
> Ellipse, but formula for circle volume do not need to use implementation of
> volume for ellipse.
Sure, it is not universal thing.
> In any case, my question was not how to implement polymorphic volume
> function.
> I asked whether it is possible to change PostgreSQL function lookup rules to
> support something like virtual calls.
You can use this hack to make it.
create or replace function volume(r base_table, t text) returns integer as $$
declare v integer;
begin execute format('select volume(r) from %I r where r.x = %L', t,
r.x) into v;
return v;
end; $$ language plpgsql;
select volume(r, tableoid::regclass::text) from base_table r;
volume
--------
2
60
(2 rows)
--
Kind regards,
Sergey Konoplev
PostgreSQL Consultant and DBA
http://www.linkedin.com/in/grayhemp
+1 (415) 867-9984, +7 (901) 903-0499, +7 (988) 888-1979
gray(dot)ru(at)gmail(dot)com
From | Date | Subject | |
---|---|---|---|
Next Message | Christian Kruse | 2013-12-30 19:52:25 | Patch: Show process IDs of processes holding a lock; show relation and tuple infos of a lock to acquire |
Previous Message | Andres Freund | 2013-12-30 16:19:01 | Re: INSERT...ON DUPLICATE KEY LOCK FOR UPDATE |