Kouhei Kaigai <kai...@ak.jp.nec.com> writes:
> I expected to include simple function pointers for copying and text-output
> as follows:

>   typedef struct {
>       Plan    plan;
>         :
>       NodeCopy_function    node_copy;
>       NodeTextOut_function node_textout;
>   } Custom;

I was thinking more like

typedef struct CustomPathFuncs {
        const char *name;       /* used for debugging purposes only */
        NodeCopy_function node_copy;
        NodeTextOut_function node_textout;
        ... etc etc etc ...
} CustomPathFuncs;

typedef struct CustomPath {
        Path path;
        const CustomPathFuncs *funcs;
        ... maybe a few more fields here, but not too darn many ...
} CustomPath;

and similarly for CustomPlan.

The advantage of this way is it's very cheap for (what I expect will be)
the common case where an extension has a fixed set of support functions
for its custom paths and plans.  It just declares a static constant
CustomPathFuncs struct, and puts a pointer to that into its paths.

If an extension really needs to set the support functions on a per-object
basis, it can do this:

typdef struct MyCustomPath {
       CustomPath cpath;
       CustomPathFuncs funcs;
       ... more fields ...
} MyCustomPath;

and then initialization of a MyCustomPath would include

        mypath->cpath.funcs = &mypath->funcs;
        mypath->funcs.node_copy = MyCustomPathCopy;
        ... etc etc ...

In this case we're arguably wasting one pointer worth of space in the
path, but considering the number of function pointers such a path will be
carrying, I don't think that's much of an objection.

>> So?  If you did that, then you wouldn't have renumbered the Vars as
>> INNER/OUTER.  I don't believe that CUSTOM_VAR is necessary at all; if it
>> is needed, then there would also be a need for an additional tuple slot
>> in executor contexts, which you haven't provided.

> For example, the enhanced postgres_fdw fetches the result set of
> remote join query, thus a tuple contains the fields come from both side.
> In this case, what varno shall be suitable to put?

Not sure what we'd do for the general case, but CUSTOM_VAR isn't the
solution.  Consider for example a join where both tables supply columns
named "id" --- if you put them both in one tupledesc then there's no
non-kluge way to identify them.

Possibly the route to a solution involves adding another plan-node
callback function that ruleutils.c would use for printing Vars in custom
join nodes.  Or maybe we could let the Vars keep their original RTE
numbers, though that would complicate life at execution time.

Anyway, if we're going to punt on add_join_path_hook for the time
being, this problem can probably be left to solve later.  It won't
arise for simple table-scan cases, nor for single-input plan nodes
such as sorts.

                        regards, tom lane

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

Reply via email to