Обсуждение: sendLong in custom communication doesn't work

Поиск
Список
Период
Сортировка

sendLong in custom communication doesn't work

От
Krystian Piećko
Дата:
Hi,

I’m implementing the functionality that will pass all the queries native to postgresql (that asks about structures and versions) to the hidden postgresql and other queries I would like to parse myself. I have a big problem with outputing PG_TYPE_INT[248] value. I’m doing it because in my system I would like to provide the method to send by jdbc XML messages that would be resolved by my software and other queries would be answered by PostgreSQL. I don’t mind the speed and the double processing I just want to learn how to do it.
Outputing texts works fine.

So when I receive native query like (select * from pg_class) I have active JDBC connection to hidden postgresql (9.3) and this query is executed on that server. When I get ResultSet from the hidden postgresql I try to output the results in postgres form to the output. Example communication that returns current date in long (in my opinion) should look like this:

//Example code that outputs current date in long format
public void sendExampleResponse() {
        server.trace("Query");
        String query = readString();
        System.out.println("query = " + query);
        long timeLong = new java.util.Date().getTime();
        startMessage('T');
        writeShort(1); //column amount
        writeString("TEST”); //column name
        writeInt(0); //object ID
        writeShort(0); // attribute number of the column (i tested by changing it to 1 or so didn’t work)
        writeInt(PG_TYPE_INT8); //type of the data - PG_TYPE_INT8
        int size = 8; 
        System.out.println("size: "+size);
        writeShort(size); //the size of this type
        writeInt(-1); pg_attribute.atttypmod
        writeShort(0);//the form of 0 ? text : binary
        sendMessage(); 
        startMessage('D’); //start outputing results
        writeShort(1); //column quantity
        int longSizeBytes=8;
        System.out.println("writeLongSize: "+longSizeBytes);
        writeInt(longSizeBytes);
        writeLong(timeLong);
        sendCommandComplete(COMMAND_TYPE.SELECT, 4);
        sendReadyForQuery();
}

WriteInt (the type of out variable is OutputStream):
It is from DataOutputStream:
    public final void writeInt(int v) throws IOException {
        out.write((v >>> 24) & 0xFF);
        out.write((v >>> 16) & 0xFF);
        out.write((v >>>  8) & 0xFF);
        out.write((v >>>  0) & 0xFF);
        incCount(4);
    }

WriteShort:
    public final void writeShort(int v) throws IOException {
        out.write((v >>> 8) & 0xFF);
        out.write((v >>> 0) & 0xFF);
        incCount(2);
    }

WriteLong:
     private byte writeBuffer[] = new byte[8];
    public final void writeLong(long v) throws IOException {
        writeBuffer[0] = (byte)(v >>> 56);
        writeBuffer[1] = (byte)(v >>> 48);
        writeBuffer[2] = (byte)(v >>> 40);
        writeBuffer[3] = (byte)(v >>> 32);
        writeBuffer[4] = (byte)(v >>> 24);
        writeBuffer[5] = (byte)(v >>> 16);
        writeBuffer[6] = (byte)(v >>>  8);
        writeBuffer[7] = (byte)(v >>>  0);
        out.write(writeBuffer, 0, 8);
        incCount(8);
    }

I did do some tests like sending 10000 times these same query that outputs what is in example changing the variable size and longSizeBytes (for 1 incrementation of size there were 100 of longSizeBytes). I checked everything. Even I analyzed the code of sendInt in PostgreSQL source code. I don’t know what to do more. Could someone help me with changing sendExampleResponse? 

BTW I’m checking how it works by connecting to my custom server using psql but the results of queries like (select test form test;) is outputted by sendExampleResponse method. \l works, \d works \d <tableName> doesn’t work. PSQL has two queries in \d <tableName>. Fist one returns oid of the table and second one outputs columns using this oid. Because OID is number (java object java.lang.Long) I can’t do much more than \l, \d :) on my custom server.

Krystian

Re: sendLong in custom communication doesn't work

От
Robert Haas
Дата:
On Fri, Jul 25, 2014 at 5:53 AM, Krystian Piećko
<krystian.piecko@gmail.com> wrote:
> I’m implementing the functionality that will pass all the queries native to
> postgresql (that asks about structures and versions) to the hidden
> postgresql and other queries I would like to parse myself. I have a big
> problem with outputing PG_TYPE_INT[248] value. I’m doing it because in my
> system I would like to provide the method to send by jdbc XML messages that
> would be resolved by my software and other queries would be answered by
> PostgreSQL. I don’t mind the speed and the double processing I just want to
> learn how to do it.
> Outputing texts works fine.
>
> So when I receive native query like (select * from pg_class) I have active
> JDBC connection to hidden postgresql (9.3) and this query is executed on
> that server. When I get ResultSet from the hidden postgresql I try to output
> the results in postgres form to the output. Example communication that
> returns current date in long (in my opinion) should look like this:
>
> //Example code that outputs current date in long format
> public void sendExampleResponse() {
>         server.trace("Query");
>         String query = readString();
>         System.out.println("query = " + query);
[ ...and there's more... ]

I don't think you're going to get much help writing Java code here; if
you want to discuss the pgsql-jdbc code, you should use that mailing
list rather than this one.  This mailing list would be the right place
for discussions about the wire protocol itself, though, so maybe
someone could give you some advice on that if you were more specific
about what problem you're having.  From the provided information it's
hard to be sure what's going wrong.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company