[Pljava-dev] VarLenTuple example code

From: thomas at tada(dot)se (Thomas Hallgren)
To:
Subject: [Pljava-dev] VarLenTuple example code
Date: 2006-10-01 11:53:52
Message-ID: 451FAC50.9060100@tada.se
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pljava-dev

Hi Markus,
I started inlining some responses to your ideas but gave it up. I like
your ideas and I think it all comes down to two different approaches;
either we do the static approach and let the send/receive and
input/output be pure static methods and deal with B<->C and A<->C
conversions or we do the more puristic OO approach and let the
send/receive and input/output take the overhead of creating Java objects
and then go from there.

Regardless of what method we choose, we will also need something that
does the C<->D conversion (i.e. SQLData).
I think we must choose one or the other and go all the way. If we go the
static approach (your advanced optimization), then we must do that for
both the input/output and the send/receive pairs. It doesn't make much
sense to do it with only one of them. The more I think about it, the
more I'm leaning towards the static approach. There are three major reasons:

1. Less overhead. Instances are only created when really needed.
2. Very easy to explain since our input, output, send, and receive will
perform the exact same work as would be done by corresponding
implementations written in C.
3. There is no such thing as parse/toString in the SQLData interface so
that's a somewhat contrived construction anyway.

So, this is what I would suggest that we do:

1. We keep the UDT[] syntax for all four methods. They stipulate the
static "interface" and should not be made arbitrary methods. If you want
a type, you have to make it adhere to this "interface" (within quotes
since it's about static methods and not a Java interface per se).
2. We still require that a type implements the SQLData interface. This
will then be used exclusively for C<->D conversions and those methods
have nothing to do with the UDT[] methods. They will be called by the
coerceObject/coerceData methods in PL/Java UDT.c (like today).

I.e. a fullblown type implementation would then have 6 methods (4
static) and look like this:

// The new static interface
//
public static void input(String input, SQLData output) throws
SQLException { ... }
public static String output(SQLData input) throws SQLException { ... }
public static void receive(SQLData input, SQLData output) throws
SQLException { ... }
public static void send(SQLData input, SQLData output) throws
SQLException { ... }

// The SQLData interface
//
public void readSQL(SQLData input, String typename) throws SQLException
{ ... }
public void writeSQL(SQLData output) throws SQLException { ... }

What do you think?

Regards,
Thomas Hallgren

Markus Schaber wrote:
>
> [Warning: Direct brain-dump follows. Anticipate confusion.]
>
> So my idea is:
>
> - Use the readSQL/writeSQL format to read and write C (internal / disk
> format) for the "type mapping". This means all the example code using
> type mapping should continue to work, no code wr/t this has to be changed.
>
> - Leave the UDT[] magic for input/output mapping as it is now, as it
> works fine, and using the toString() semantics is nice.
>
> - Drop the UDT[] magic for send/receive, and allow the users to define
> them as "normal" static methods.
>
> The only problem when implementing the send/receive functions as static
> methods was that the pseudo type "internal" parameter is not mapped
> usefully. In my eyes, mapping the "internal" parameter from receive
> (which is an StringInfo in PG_GETARG_POINTER(0) internally) to an
> SQLInput object should be the easiest way to solve that problem.
>
> (It's a bit misleading to call that pseudo type "internal" despite the
> fact that it carries the external representation in this case. One might
> think the PostgreSQL core hackers celebrate some kind of cynism. :-)
>
> This way, it's possible to implement both send() and receive() as static
> methods in plain java, each implementing one way of a clean conversion
> between the Java object and the serialized, external B form.
>
> Actually, this are C->D->B and B->D->C conversions. The C->D and D->B is
> handled by the existing type mapping. Just look how my VarLenTuple is
> coded, that's what I have in mind.
>
>
>
> While meditating, I came to the following conclusion: AFAICS, there's
> already a mapping in place for CString to Java Strings, so input/output
> functions seem to be implementable with static methods instead of UDT[]
> magic, if wanted. And keeping the UDT[] magic code in place for send/
> receive will not hurt either, so users can use it when they think it
> fits their needs (having equal B and C formats).
>
>
> Advanced optimization:
> For efficiency reasons, it might be useful to have send() and receive()
> convert directly between C and B, without the intermediate D step. This
> could be made by having both methods working on a pair of SQLInput/
> SQLOutput, but we'd need some additional magic to be able to declare
> such methods, I think. Maybe we could introduce some declaration that
> allows a function to receive and send SQLInput/SQLOutput directly,
> without calling the type mapping code, thus they could work with the
> on-disk representation directly, a kinda "high speed" path. But I'm
> afraid that would be highly PostgreSQL specific and not portable in any way.
>
> Phew.
> I think I'll need another night or two to think about all that, but at
> least at the moment, it seems to make sense for me. :-)
>
> Thanks,
> Markus
>

In response to

Responses

Browse pljava-dev by date

  From Date Subject
Next Message Markus Schaber 2006-10-01 12:38:37 [Pljava-dev] VarLenTuple example code
Previous Message Thomas Hallgren 2006-09-29 19:12:00 [Pljava-dev] Newbie Questions