Re: dblink: add polymorphic functions.

From: Merlin Moncure <mmoncure(at)gmail(dot)com>
To: Corey Huinker <corey(dot)huinker(at)gmail(dot)com>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: dblink: add polymorphic functions.
Date: 2015-07-06 13:26:58
Message-ID: CAHyXU0y7MvPsQ9e_Dum4W+vXFRmm5ukmg63JN_toPkugv65mgQ@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Thu, Feb 19, 2015 at 4:06 PM, Corey Huinker <corey(dot)huinker(at)gmail(dot)com> wrote:
> In the course of writing a small side project which hopefully will make its
> way onto pgxn soon, I was writing functions that had a polymorphic result
> set.
>
> create function foo( p_row_type anyelement, p_param1 ...) returns setof
> anyelement
>
> Inside that function would be multiple calls to dblink() in both synchronous
> and async modes. It is a requirement of the function that each query return
> a result set conforming to the structure passed into p_row_type, but there
> was no way for me to express that.
>
> Unfortunately, there's no way to say
>
>
> select * from dblink_get_result('connname') as <polymorphic record type>;
>
>
> Instead, I had to generate the query as a string like this.
>
> with x as (
> select a.attname || ' ' || pg_catalog.format_type(a.atttypid,
> a.atttypmod) as sql_text
> from pg_catalog.pg_attribute a
> where a.attrelid = pg_typeof(p_row_type)::text::regclass
> and a.attisdropped is false
> and a.attnum > 0
> order by a.attnum )
> select format('select * from dblink_get_result($1) as
> t(%s)',string_agg(x.sql_text,','))
> from x;
>
> Moreover, I'm now executing this string dynamically, incurring reparsing and
> replanning each time (and if all goes well, this would be executed many
> times). Granted, I could avoid that by rewriting the stored procedure in C
> and using prepared statements (not available in PL/PGSQL), but it seemed a
> shame that dblink couldn't itself handle this polymorphism.
>
> So with a little help, we were able to come up with polymorphic set
> returning dblink functions.
>
> Below is the results of the patch applied to a stock 9.4 installation.
>
> [local]:ubuntu(at)dblink_test# create extension dblink;
> CREATE EXTENSION
> Time: 12.778 ms
> [local]:ubuntu(at)dblink_test# \df dblink
> List of functions
> Schema | Name | Result data type | Argument data types |
> Type
> --------+--------+------------------+---------------------------------+--------
> public | dblink | SETOF record | text |
> normal
> public | dblink | SETOF anyelement | text, anyelement |
> normal
> public | dblink | SETOF record | text, boolean |
> normal
> public | dblink | SETOF anyelement | text, boolean, anyelement |
> normal
> public | dblink | SETOF record | text, text |
> normal
> public | dblink | SETOF anyelement | text, text, anyelement |
> normal
> public | dblink | SETOF record | text, text, boolean |
> normal
> public | dblink | SETOF anyelement | text, text, boolean, anyelement |
> normal
> (8 rows)

sorry for the late reply. I'm a little concerned about the state of
overloading here. If I'm not mistaken, you may have introduced a
pretty serious backwards compatibility issue. Having the two
signatures (text, anyelement) and (text, boolean) will now fail
anytime (unknown, unknown) is passed, and that's a pretty common
invocation. If I'm right, quickly scanning the function list, I don't
think there's an easy solution to this issue other than adding an
alternately named call.

merlin

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2015-07-06 13:30:28 Re: PATCH:do not set Win32 server-side socket buffer size on windows 2012
Previous Message Stephen Frost 2015-07-06 13:23:12 Re: Idea: closing the loop for "pg_ctl reload"