Re: Polymorphic function calls

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

In response to

Browse pgsql-hackers by date

  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