Thread: Using callable statements

Using callable statements

From
Juan Francisco Diaz
Date:
Hi, id like to know how to use a callable statement that call aa function
that returns a SETFOF RECORD. How do i give the list of column names?

Thanks

JuanF
(a newbie in evolution)


Help - lo_close: invalid large obj descriptor

From
Toby
Date:
I've read the docs, I've searched the web.

I'm running PGSql 7.3.4 under Cygwin 1.3.22.1, J2SE 1.4.2, latest stable JDBC v3 drivers (pg73jdbc3.jar). This is all running on the same machine, a dual AMD with 1GB memory.

Accessing the database works fine, but when I try to write to a newly created LargeObject it always fails with

org.postgresql.util.PSQLException - FastPath call returned ERROR:  lo_write: invalid large obj descriptor (0)

The code below illustrates this.

The code is actually going to be used within a Tomcat webapp, but I had to use Jdbc3ConnectionPool since that was the only pool that returned connections that were castable to a PGConnection. I get the same error from inside and outside Tomcat. Thought the error might be related to permissions writing large objects so I tried the following which didn't help.

        GRANT ALL ON "pg_largeobject" TO "web";

I also tried not using the connection pool, and instead just using the straight DriverManager.getConnection() instead, but that fails on the lo.write() call too.

I've had large objects working fine on another project (same dev machine) a coupla years ago (pg 7.2.x), so I don't think its a case of HOW I'm doing it, I suspect there's a bug.

Can someone shed some light?


import java.io.File;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import org.postgresql.PGConnection;
import org.postgresql.jdbc3.Jdbc3ConnectionPool;
import org.postgresql.largeobject.LargeObject;
import org.postgresql.largeobject.LargeObjectManager;

public class TestHarness
{
   
public static void main(String[] args)
    {
        LargeObject lo =
null;
        Connection conn =
null;
       
try
        {
           
//get a connection that's PGConnection-castable.
            //PoolingDataSource- tried 'n died
            //Jdbc3PoolingDataSource- tried 'n died
            Jdbc3ConnectionPool source = new Jdbc3ConnectionPool();
            source.setServerName(
"ash");
            source.setDatabaseName(
"adserver");
            source.setUser(
"web");
            source.setPassword(
"web");
            source.setDefaultAutoCommit(
false);

           
//just to be sure - it always says true so that's good
            //Class.forName("org.postgresql.Driver");
            //conn = DriverManager.getConnection("jdbc:postgresql://ash/adserver", "web", "web");
            conn = source.getConnection();
            System.out.println(conn.getAutoCommit());

           
//this only works for connections from Jdbc3ConnectionPool
            PGConnection pgconn = (PGConnection)conn;

           
//create the largeobject and prepare to write to it
            LargeObjectManager lom = pgconn.getLargeObjectAPI();
           
int oid = lom.create(LargeObjectManager.READ | LargeObjectManager.WRITE);
            lo = lom.open(oid, LargeObjectManager.WRITE);

           
//the thing to write
            File file = new File("D:\\downloads\\images\\banner.GIF");
            FileInputStream fis =
new FileInputStream(file);

           
//prepare a buffer (small enough to force multiple loop iterations
            //so we test it properly)
            byte buff[] = new byte[1024];

           
//now write the image
            int bytes_read;
           
while ((bytes_read = fis.read(buff, 0, buff.length)) > 0)
            {
                System.out.println(
"bytes_read=" + bytes_read);
               
//ERROR HAPPENS NEXT
                //ERROR HAPPENS NEXT
                //ERROR HAPPENS NEXT
               lo.write(buff, 0, bytes_read);
            }

           
//clean up
            fis.close();
            System.out.println(
"done");
        }
       
catch (Exception e)
        {
            System.out.println(e.getClass().getName() +
" - " + e.getMessage());
        }
       
finally
        {
           
if (lo != null)    try{lo.close();}catch (SQLException e){}
           
if (conn != null) try{conn.close();}catch (SQLException e){}
        }
    }
}

Re: Using callable statements

From
Barry Lind
Date:
Juan,

Check out the current development (7.4) version of the docs.  (you can
find a link to them from developer.postgresql.org.  There is an example
in the jdbc documentation here on how to get a ResultSet back from a
function.  Note that this only works on the current development version
of the driver (i.e. download the 7.4 driver from jdbc.postgresql.org).

thanks,
--Barry


Juan Francisco Diaz wrote:
> Hi, id like to know how to use a callable statement that call aa function
> that returns a SETFOF RECORD. How do i give the list of column names?
>
> Thanks
>
> JuanF
> (a newbie in evolution)
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: Have you checked our extensive FAQ?
>
>                http://www.postgresql.org/docs/faqs/FAQ.html
>




Re: Help - lo_close: invalid large obj descriptor

From
Barry Lind
Date:
Toby,

You need to have autocommit turned off in order to use large objects.
If I add a call to setAutocommit(false) for the connection everything
works fine.

thanks,
--Barry


Toby wrote:
> I've read the docs, I've searched the web.
>
> I'm running PGSql 7.3.4 under Cygwin 1.3.22.1, J2SE 1.4.2, latest stable
> JDBC v3 drivers (pg73jdbc3.jar). This is all running on the same
> machine, a dual AMD with 1GB memory.
>
> Accessing the database works fine, but when I try to write to a newly
> created LargeObject it always fails with
>
> org.postgresql.util.PSQLException - FastPath call returned ERROR:
> lo_write: invalid large obj descriptor (0)
>
> The code below illustrates this.
>
> The code is actually going to be used within a Tomcat webapp, but I had
> to use Jdbc3ConnectionPool since that was the only pool that returned
> connections that were castable to a PGConnection. I get the same error
> from inside and outside Tomcat. Thought the error might be related to
> permissions writing large objects so I tried the following which didn't
> help.
>
>         GRANT ALL ON "pg_largeobject" TO "web";
>
> I also tried not using the connection pool, and instead just using the
> straight DriverManager.getConnection() instead, but that fails on the
> lo.write() call too.
>
> I've had large objects working fine on another project (same dev
> machine) a coupla years ago (pg 7.2.x), so I don't think its a case of
> HOW I'm doing it, I suspect there's a bug.
>
> Can someone shed some light?
>
>
> import java.io.File;
> import java.io.FileInputStream;
> import java.sql.Connection;
> import java.sql.DriverManager;
> import java.sql.SQLException;
>
> import org.postgresql.PGConnection;
> import org.postgresql.jdbc3.Jdbc3ConnectionPool;
> import org.postgresql.largeobject.LargeObject;
> import org.postgresql.largeobject.LargeObjectManager;
>
> public class TestHarness
> {
>     public static void main(String[] args)
>     {
>         LargeObject lo = null;
>         Connection conn = null;
>         try
>         {
>             //get a connection that's PGConnection-castable.
>             //PoolingDataSource- tried 'n died
>             //Jdbc3PoolingDataSource- tried 'n died
>             Jdbc3ConnectionPool source = new Jdbc3ConnectionPool();
>             source.setServerName("ash");
>             source.setDatabaseName("adserver");
>             source.setUser("web");
>             source.setPassword("web");
>             source.setDefaultAutoCommit(false);
>
>             //just to be sure - it always says true so that's good
>             //Class.forName("org.postgresql.Driver");
>             //conn =
> DriverManager.getConnection("jdbc:postgresql://ash/adserver", "web",
> "web");
>             conn = source.getConnection();
>             System.out.println(conn.getAutoCommit());
>
>             //this only works for connections from Jdbc3ConnectionPool
>             PGConnection pgconn = (PGConnection)conn;
>
>             //create the largeobject and prepare to write to it
>             LargeObjectManager lom = pgconn.getLargeObjectAPI();
>             int oid = lom.create(LargeObjectManager.READ |
> LargeObjectManager.WRITE);
>             lo = lom.open(oid, LargeObjectManager.WRITE);
>
>             //the thing to write
>             File file = new File("D:\\downloads\\images\\banner.GIF");
>             FileInputStream fis = new FileInputStream(file);
>
>             //prepare a buffer (small enough to force multiple loop
> iterations
>             //so we test it properly)
>             byte buff[] = new byte[1024];
>
>             //now write the image
>             int bytes_read;
>             while ((bytes_read = fis.read(buff, 0, buff.length)) > 0)
>             {
>                 System.out.println("bytes_read=" + bytes_read);
>                 //ERROR HAPPENS NEXT
>                 //ERROR HAPPENS NEXT
>                 //ERROR HAPPENS NEXT
>                lo.write(buff, 0, bytes_read);
>             }
>
>             //clean up
>             fis.close();
>             System.out.println("done");
>         }
>         catch (Exception e)
>         {
>             System.out.println(e.getClass().getName() + " - " +
> e.getMessage());
>         }
>         finally
>         {
>             if (lo != null)    try{lo.close();}catch (SQLException e){}
>             if (conn != null) try{conn.close();}catch (SQLException e){}
>         }
>     }
> }
>
>




Re: Help - lo_close: invalid large obj descriptor

From
Oliver Jowett
Date:
On Wed, Aug 27, 2003 at 12:36:24PM -0700, Barry Lind wrote:
> Toby,
>
> You need to have autocommit turned off in order to use large objects.
> If I add a call to setAutocommit(false) for the connection everything
> works fine.

Does this imply that setDefaultAutoCommit is broken, then?

> >            Jdbc3ConnectionPool source = new Jdbc3ConnectionPool();
> >            source.setServerName("ash");
> >            source.setDatabaseName("adserver");
> >            source.setUser("web");
> >            source.setPassword("web");
> >            source.setDefaultAutoCommit(false);

> >            conn = source.getConnection();
> >            System.out.println(conn.getAutoCommit());

-O

Re: Help - lo_close: invalid large obj descriptor

From
Toby Doig
Date:
> On Wed, Aug 27, 2003 at 12:36:24PM -0700, Barry Lind wrote:
> > Toby,
> >
> > You need to have autocommit turned off in order to use large objects.
> > If I add a call to setAutocommit(false) for the connection everything
> > works fine.

yes, i know. and the autocommit was indeed set to false.

> > >            source.setDefaultAutoCommit(false);
see? i did set it.

> > >            System.out.println(conn.getAutoCommit());
and i verified it here.

t

Re: Help - lo_close: invalid large obj descriptor

From
Barry Lind
Date:

Toby Doig wrote:
>>On Wed, Aug 27, 2003 at 12:36:24PM -0700, Barry Lind wrote:
>>
>>>Toby,
>>>
>>>You need to have autocommit turned off in order to use large objects.
>>>If I add a call to setAutocommit(false) for the connection everything
>>>works fine.
>
>
> yes, i know. and the autocommit was indeed set to false.
>
>
>>>>           source.setDefaultAutoCommit(false);
>
> see? i did set it.

I don't think this method currently does anything.

>
>
>>>>           System.out.println(conn.getAutoCommit());
>
> and i verified it here.
>

Yes you verified that AutoCommit was on.  At least when I run your test
program the above println prints 'true', which means autocommit is on
and thus the problem.

thanks,
--Barry




Re: Help - lo_close: invalid large obj descriptor

From
Barry Lind
Date:

Oliver Jowett wrote:
>
>
> Does this imply that setDefaultAutoCommit is broken, then?
>
Yes I believe this method doesn't really do anything.  Although since it
is neither part of the jdbc api nor part of the documented postgresql
extentions to the jdbc api, I don't consider it a significant problem.
Perhaps it should just be removed, since I don't know if the jdbc spec
even allows a connection pool to return a connection in any state other
than the documented default of autocommit on.

thanks,
--Barry








Re: Help - lo_close: invalid large obj descriptor

From
Toby Doig
Date:
aargh, my apologies barry. you were, of course, correct. the println()
call was dumping true and i was misreading it. call it tiredness. or
carelessness.

i actually wrap the pgs connection pool object around my own connection
pool so that all getConnection() calls now go through my own method. i can
then ensure that the autocommit is off (i also set transaction params).

t