[Pljava-dev] VarLenTuple example code

From: thomas at tada(dot)se (Thomas Hallgren)
To:
Subject: [Pljava-dev] VarLenTuple example code
Date: 2006-09-28 13:49:40
Message-ID: 451BD2F4.60202@tada.se
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pljava-dev

Hmm, perhaps just an oversight, bot you don't have UDT syntax on the
send/receive methods, i.e. this line:

+ AS 'org.postgresql.pljava.example.VarLenTuple.receive'

should read

+ AS 'UDT[org.postgresql.pljava.example.VarLenTuple] receive'

Regards,
Thomas Hallgren

Markus Schaber wrote:
> Hi, Thomas,
>
> Here's a small example I implemented for variable length data types.
>
> It's not useful for anything but an example.
>
> I included the source, as well as the diff for the examples.ddr file, so
> regard it as contribution.
>
> It all seems to work fine, apart from one small problem:
>
>
>> [local]:pljavatest=# copy foo to '/tmp/foo' binary;
>> COPY
>> [local]:pljavatest=# copy foo from '/tmp/foo' binary;
>> ERROR: Unable to find static method
>> org.postgresql.pljava.example.VarLenTuple.receive
>> with signature
>> (Ljava/lang/String;)Lorg/postgresql/pljava/example/VarLenTuple;
>> CONTEXT: COPY foo, line 1, column t
>>
>
> >From our discussion, I had the impression that the receive method
> will get an VarLenTuple instance (as I created a type mapping)
> and not a String instance.
>
> Thanks,
> Markus
>
> ------------------------------------------------------------------------
>
> Index: src/java/examples/deployment/examples.ddr
> ===================================================================
> RCS file: /usr/local/cvsroot/pljava/org.postgresql.pljava/src/java/examples/deployment/examples.ddr,v
> retrieving revision 1.35
> diff -u -r1.35 examples.ddr
> --- src/java/examples/deployment/examples.ddr 13 May 2006 09:18:38 -0000 1.35
> +++ src/java/examples/deployment/examples.ddr 28 Sep 2006 13:29:26 -0000
> @@ -430,6 +430,57 @@
> AS 'org.postgresql.pljava.example.ComplexTuple.logAndReturn'
> LANGUAGE java IMMUTABLE STRICT;
>
> + /*
> + * Shell Type Definition for VarLenTuple:
> + */
> + CREATE FUNCTION javatest.varlentuple(cstring) RETURNS javatest.varlentuple AS 'lower' LANGUAGE INTERNAL;
> +
> + /* The scalar input function */
> + CREATE FUNCTION varlentuple_in(cstring)
> + RETURNS javatest.varlentuple
> + AS 'UDT[org.postgresql.pljava.example.VarLenTuple] input'
> + LANGUAGE java IMMUTABLE STRICT;
> +
> + /* The scalar output function */
> + CREATE FUNCTION varlentuple_out(javatest.varlentuple)
> + RETURNS cstring
> + AS 'UDT[org.postgresql.pljava.example.VarLenTuple] output'
> + LANGUAGE java IMMUTABLE STRICT;
> +
> + /* The scalar receive function */
> + CREATE FUNCTION varlentuple_recv(internal)
> + RETURNS javatest.varlentuple
> + AS 'org.postgresql.pljava.example.VarLenTuple.receive'
> + LANGUAGE java IMMUTABLE STRICT;
> +
> + /* The scalar send function */
> + CREATE FUNCTION varlentuple_send(javatest.varlentuple)
> + RETURNS bytea
> + AS 'org.postgresql.pljava.example.VarLenTuple.send'
> + LANGUAGE java IMMUTABLE STRICT;
> +
> + /* The scalar type declaration */
> + CREATE TYPE javatest.varlentuple (
> + internallength = -1,
> + input = javatest.varlentuple_in,
> + output = javatest.varlentuple_out,
> + receive = javatest.varlentuple_recv,
> + send = javatest.varlentuple_send,
> + alignment = int4
> + );
> +
> + /* A test function that just logs and returns its argument.
> + */
> + CREATE FUNCTION javatest.logvarlentuple(javatest.varlentuple)
> + RETURNS javatest.varlentuple
> + AS 'org.postgresql.pljava.example.VarLenTuple.logAndReturn'
> + LANGUAGE java IMMUTABLE STRICT;
> +
> + /* Install the actual type mapping.
> + */
> + SELECT sqlj.add_type_mapping('javatest.varlentuple', 'org.postgresql.pljava.example.VarLenTuple');
> +
> +
> /*
> * An example using the ANY type
> */
>
> ------------------------------------------------------------------------
>
> /*
> * Copyright (c) 2004, 2005, 2006 TADA AB - Taby Sweden
> * Copyright (c) 2006 Markus Schaber <schabi at logix-tt.com>
> * Distributed under the terms shown in the file COPYRIGHT
> * found in the root directory of this distribution or at
> * http://eng.tada.se/osprojects/COPYRIGHT.html
> */
> package org.postgresql.pljava.example;
>
> import java.io.ByteArrayOutputStream;
> import java.io.DataOutputStream;
> import java.io.IOException;
> import java.nio.ByteOrder;
> import java.sql.SQLData;
> import java.sql.SQLException;
> import java.sql.SQLInput;
> import java.sql.SQLOutput;
> import java.util.logging.Logger;
>
>
> /** Datatype implementing a variable length Tuple of Doubles.
> *
> * Not really useful except as an example and test for implementing fully fledged VARLENA datatyes
> * including custom binary representation via Java. Code is intentionally kept simple, for the sake
> * of efficency, and based on the ComplexTuple example.
> * @author schabi
> *
> */
> public class VarLenTuple implements SQLData
> {
> private static Logger s_logger = Logger.getAnonymousLogger();
>
> private static final String m_typeName = "javatest.varlentuple";
>
> private static final double[] EMPTY = {};
>
> private double[] arr = EMPTY;
>
> public static VarLenTuple parse(String input, String typeName) throws SQLException
> {
> checkType(typeName);
> if ((input == null) || (input.length()<2) || (input.charAt(0)!='(') || (input.charAt(input.length()-1) != ')') ) {
> throw new SQLException("Illegal value for "+m_typeName+": "+input);
> }
>
> if (input.length()==2) {
> return new VarLenTuple();
> }
> String[] parts = input.substring(1, input.length()-1).split(",");
>
> double[] temparr = new double[parts.length];
>
> for (int i=0; i < parts.length; i++) {
> try {
> temparr[i] = Double.parseDouble(parts[i]);
> } catch (NumberFormatException e) {
> throw new SQLException("Bad double '"+parts[i]+"' while parsing "+m_typeName+": "+e.getMessage());
> }
> }
>
> return new VarLenTuple(temparr);
>
> }
>
> private static void checkType(String typeName) throws SQLException {
> if (!m_typeName.equalsIgnoreCase(typeName)) {
> throw new SQLException("parser for "+m_typeName+" cannot deserialize type "+typeName+"!");
> }
> }
>
> public VarLenTuple()
> {
> }
>
> public VarLenTuple(double[] arr)
> {
> this.arr = arr;
> }
>
> public String getSQLTypeName()
> {
> return m_typeName;
> }
>
> public void readSQL(SQLInput stream, String typeName) throws SQLException
> {
> s_logger.info(typeName + " from SQLInput");
> checkType(typeName);
>
> // fetch PostgreSQL VarLenA Header
> int bin_size = stream.readInt() & 0x3fffffff;
> int count = (bin_size - 4)/8;
>
> if (bin_size != (count*8 +4))
> {
> throw new SQLException("Bad Size Header!");
> }
>
> double[] temparr = new double[count];
>
> for (int i=0; i < count; i++)
> {
> temparr[i] = stream.readDouble();
> }
>
> // all went well, we can assign the value
> arr = temparr;
> }
>
> public void writeSQL(SQLOutput stream) throws SQLException
> {
> s_logger.info(m_typeName + " to SQLOutput");
> int count = arr.length;
>
> stream.writeInt(count*8 +4);
> for (int i=0; i < count; i++)
> {
> stream.writeDouble(arr[i]);
> }
> }
>
> public String toString()
> {
> s_logger.info(m_typeName + " toString");
> StringBuffer sb = new StringBuffer();
> sb.append('(');
> if (arr.length>0)
> {
> sb.append(arr[0]);
> for (int i=1; i < arr.length; i++)
> {
> sb.append(',');
> sb.append(arr[i]);
> }
> }
> sb.append(')');
> return sb.toString();
> }
>
> public static VarLenTuple logAndReturn(VarLenTuple cpl)
> {
> s_logger.info(cpl.getSQLTypeName() + cpl);
> return cpl;
> }
>
> public static VarLenTuple receive(SQLInput input) throws SQLException {
> int count = input.readInt();
> // we have to swap, as we use network byte order for external representation
> if (ByteOrder.nativeOrder()==ByteOrder.LITTLE_ENDIAN) {
> count = Integer.reverseBytes(count);
> }
>
> if (count==0) {
> return new VarLenTuple();
> }
> double[] temparr = new double[count];
>
> if (ByteOrder.nativeOrder()==ByteOrder.LITTLE_ENDIAN) {
> for (int i=0; i < count; i++) {
> temparr[i] = Double.longBitsToDouble(Long.reverseBytes(input.readLong()));
> }
> } else {
> for (int i=0; i < count; i++) {
> temparr[i] = input.readDouble();
> }
>
> }
> return new VarLenTuple(temparr);
> }
>
> public static byte[] send(VarLenTuple input) throws SQLException {
> double[] temparr = input.arr;
> int count = temparr.length;
>
> ByteArrayOutputStream bos = new ByteArrayOutputStream(count*8+4);
>
> //DataOutputStream always uses Network Byte Order (Big Endian)
> DataOutputStream os = new DataOutputStream(bos);
> try {
> os.writeInt(count);
>
> for (int i=0; i < count; i++) {
> os.writeDouble(temparr[i]);
> }
> os.flush();
> } catch (IOException e) {
> throw new SQLException("Error writing temporary buffer: "+e.getMessage());
> }
> return bos.toByteArray();
>
> }
> }
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Pljava-dev mailing list
> Pljava-dev at gborg.postgresql.org
> http://gborg.postgresql.org/mailman/listinfo/pljava-dev
>

In response to

Responses

Browse pljava-dev by date

  From Date Subject
Next Message Markus Schaber 2006-09-28 14:04:00 [Pljava-dev] VarLenTuple example code
Previous Message Markus Schaber 2006-09-28 13:40:01 [Pljava-dev] VarLenTuple example code