Re: Polymorphic function calls - Mailing list pgsql-hackers
From | Sergey Konoplev |
---|---|
Subject | Re: Polymorphic function calls |
Date | |
Msg-id | CAL_0b1tBxWy_VtDzU73M5cEc_ARECQwYDijsm2GQU+TsYmhdjw@mail.gmail.com Whole thread Raw |
In response to | Re: Polymorphic function calls (knizhnik <knizhnik@garret.ru>) |
List | pgsql-hackers |
On Mon, Dec 30, 2013 at 2:03 AM, knizhnik <knizhnik@garret.ru> wrote: > On 12/30/2013 01:22 AM, Sergey Konoplev wrote: >> On Sun, Dec 29, 2013 at 8:44 AM, knizhnik <knizhnik@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;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.ru@gmail.com
pgsql-hackers by date: