fdw_private and (List*) handling in FDW API

Lists: pgsql-hackers
From: "Tomas Vondra" <tv(at)fuzzy(dot)cz>
To: "PostgreSQL-development" <pgsql-hackers(at)postgresql(dot)org>
Subject: fdw_private and (List*) handling in FDW API
Date: 2013-10-18 14:05:03
Message-ID: 9055df78ae2d481d05ee805dfc63c3d5.squirrel@sq.gransy.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Hi,

I've been exploring the new FDW API in the past few days, and I'm slightly
confused by the fdw_private fields. A few comments:

1) Generally all the API functions pass data using fields in the nodes
(e.g. GetForeignRelSize uses baserel->fdw_private etc.), but
PlanForeignModify simply returns the data, and BeginForeignModify accepts
that as a regular parameter. Is there any particular reason not to adapt
the same approach in all cases, i.e. either return the private data in all
cases (and pass as parameters), or passing them inside node/plan/...?

2) Is there any particular reason why PlanForeignModify/BeginForeignModify
require the fdw_private to be a List*, and not a generic pointer? I mean,
RelOptInfo declares fdw_private as a (void*) but the other structures
(e.g. ForeignScan) switches to (List*) for some reason. But all the
optimizer does with this data is this in createplan.c

fdw_private_list = NIL;
i = 0;
foreach(lc, resultRelations)
{
...
fdw_private = fdwroutine->PlanForeignModify(root, node, rti, i);
fdw_private_list = lappend(fdw_private_list, fdw_private);
i++;
}

node->fdwPrivLists = fdw_private_list;
return node;

If I read that correctly, it just accumulates all the lists into a single
list (and then unpacks that into individual lists in nodeModifyTable.c).
What is the reason for using (List*) here? I'd rather use a structure
here, not generic lists, YMMV. Or is there something I missed (e.g. future
plans)?

regards
Tomas


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: "Tomas Vondra" <tv(at)fuzzy(dot)cz>
Cc: "PostgreSQL-development" <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: fdw_private and (List*) handling in FDW API
Date: 2013-10-18 15:52:36
Message-ID: 8913.1382111556@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

"Tomas Vondra" <tv(at)fuzzy(dot)cz> writes:
> 2) Is there any particular reason why PlanForeignModify/BeginForeignModify
> require the fdw_private to be a List*, and not a generic pointer?

That data has to be copiable by copyObject(), which a generic void* is
not. We could perhaps have made it Node* instead, but that would only
work conveniently if there were infrastructure for plugins to create new
first-class Node types; which there isn't. A List is often the easiest
way to transport a few random values from plan time to execution time,
so it seemed best to declare fdw_private that way.

regards, tom lane


From: "Tomas Vondra" <tv(at)fuzzy(dot)cz>
To: "Tom Lane" <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: "Tomas Vondra" <tv(at)fuzzy(dot)cz>, "PostgreSQL-development" <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: fdw_private and (List*) handling in FDW API
Date: 2013-10-18 16:06:04
Message-ID: ddb8a34ba631a2e1b2a11d93d740bd0c.squirrel@sq.gransy.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On 18 Říjen 2013, 17:52, Tom Lane wrote:
> "Tomas Vondra" <tv(at)fuzzy(dot)cz> writes:
>> 2) Is there any particular reason why
>> PlanForeignModify/BeginForeignModify
>> require the fdw_private to be a List*, and not a generic pointer?
>
> That data has to be copiable by copyObject(), which a generic void* is
> not. We could perhaps have made it Node* instead, but that would only
> work conveniently if there were infrastructure for plugins to create new
> first-class Node types; which there isn't. A List is often the easiest
> way to transport a few random values from plan time to execution time,
> so it seemed best to declare fdw_private that way.

Oh, I see. Thanks for explanation.

Tomas