On Mon, Dec 30, 2013 at 2:03 AM, knizhnik <knizh...@garret.ru> wrote:
> On 12/30/2013 01:22 AM, Sergey Konoplev wrote:
>> On Sun, Dec 29, 2013 at 8:44 AM, knizhnik <knizh...@garret.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;
(2 rows)

Kind regards,
Sergey Konoplev
PostgreSQL Consultant and DBA

+1 (415) 867-9984, +7 (901) 903-0499, +7 (988) 888-1979

Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:

Reply via email to