Commit 2232172e authored by Barry Lind's avatar Barry Lind

JDBC checkin fixing the following bugs:

  Fixed support in the driver for notifications (added PGConnection.getNotifications()) - problem reported by Benjamin.Feinstein@guardent.com
  Worked around server problems with int8/int2 and constants; quote values when they are intended to bind to an int8/int2 column - reported by many
  Fixed bug in the Array interface with string parsing not handling escaped characters correctly - reported by devajx@yahoo.com
  Added workaround to support 'infinity' and '-infinity' for dates - reported bydmitry@openratings.com
  Fixed some performance issues with setBlob - reported by d.wall@computer.org
  Added support for using new prepared statements functionality in 7.3 (added PGStatement.setUseServerPrepare() and isUseServerPrepare() methods)

 Modified Files:
 	jdbc/org/postgresql/PGConnection.java
 	jdbc/org/postgresql/PGStatement.java
 	jdbc/org/postgresql/core/QueryExecutor.java
 	jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java
 	jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java
 	jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java
 	jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java
 	jdbc/org/postgresql/jdbc2/Array.java
 Added Files:
 	jdbc/org/postgresql/PGNotification.java
 	jdbc/org/postgresql/core/Notification.java
parent 97ac1032
...@@ -7,7 +7,7 @@ import org.postgresql.core.Encoding; ...@@ -7,7 +7,7 @@ import org.postgresql.core.Encoding;
import org.postgresql.fastpath.Fastpath; import org.postgresql.fastpath.Fastpath;
import org.postgresql.largeobject.LargeObjectManager; import org.postgresql.largeobject.LargeObjectManager;
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Attic/PGConnection.java,v 1.1 2002/07/23 03:59:55 barry Exp $ /* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Attic/PGConnection.java,v 1.2 2002/09/02 03:07:36 barry Exp $
* This interface defines PostgreSQL extentions to the java.sql.Connection interface. * This interface defines PostgreSQL extentions to the java.sql.Connection interface.
* Any java.sql.Connection object returned by the driver will also implement this * Any java.sql.Connection object returned by the driver will also implement this
* interface * interface
...@@ -68,5 +68,14 @@ public interface PGConnection ...@@ -68,5 +68,14 @@ public interface PGConnection
*/ */
public Object getObject(String type, String value) throws SQLException; public Object getObject(String type, String value) throws SQLException;
/*
* This method returns any notifications that have been received
* since the last call to this method.
* Returns null if there have been no notifications.
*/
public PGNotification[] getNotifications();
} }
package org.postgresql;
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Attic/PGNotification.java,v 1.1 2002/09/02 03:07:36 barry Exp $
* This interface defines PostgreSQL extention for Notifications
*/
public interface PGNotification
{
/*
* Returns name of this notification
*/
public String getName();
/*
* Returns the process id of the backend process making this notification
*/
public int getPID();
}
...@@ -3,7 +3,7 @@ package org.postgresql; ...@@ -3,7 +3,7 @@ package org.postgresql;
import java.sql.*; import java.sql.*;
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Attic/PGStatement.java,v 1.3 2002/07/23 03:59:55 barry Exp $ /* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Attic/PGStatement.java,v 1.4 2002/09/02 03:07:36 barry Exp $
* This interface defines PostgreSQL extentions to the java.sql.Statement interface. * This interface defines PostgreSQL extentions to the java.sql.Statement interface.
* Any java.sql.Statement object returned by the driver will also implement this * Any java.sql.Statement object returned by the driver will also implement this
* interface * interface
...@@ -18,4 +18,8 @@ public interface PGStatement ...@@ -18,4 +18,8 @@ public interface PGStatement
*/ */
public long getLastOID() throws SQLException; public long getLastOID() throws SQLException;
public void setUseServerPrepare(boolean flag);
public boolean isUseServerPrepare();
} }
package org.postgresql.core;
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/core/Attic/Notification.java,v 1.1 2002/09/02 03:07:36 barry Exp $
* This is the implementation of the PGNotification interface
*/
public class Notification implements org.postgresql.PGNotification
{
public Notification(String p_name, int p_pid) {
m_name = p_name;
m_pid = p_pid;
}
/*
* Returns name of this notification
*/
public String getName() {
return m_name;
}
/*
* Returns the process id of the backend process making this notification
*/
public int getPID() {
return m_pid;
}
private String m_name;
private int m_pid;
}
...@@ -13,7 +13,7 @@ import org.postgresql.util.PSQLException; ...@@ -13,7 +13,7 @@ import org.postgresql.util.PSQLException;
* <p>The lifetime of a QueryExecutor object is from sending the query * <p>The lifetime of a QueryExecutor object is from sending the query
* until the response has been received from the backend. * until the response has been received from the backend.
* *
* $Id: QueryExecutor.java,v 1.14 2002/08/23 20:45:49 barry Exp $ * $Id: QueryExecutor.java,v 1.15 2002/09/02 03:07:36 barry Exp $
*/ */
public class QueryExecutor public class QueryExecutor
...@@ -75,6 +75,7 @@ public class QueryExecutor ...@@ -75,6 +75,7 @@ public class QueryExecutor
case 'A': // Asynchronous Notify case 'A': // Asynchronous Notify
int pid = pg_stream.ReceiveInteger(4); int pid = pg_stream.ReceiveInteger(4);
String msg = pg_stream.ReceiveString(connection.getEncoding()); String msg = pg_stream.ReceiveString(connection.getEncoding());
connection.addNotification(new org.postgresql.core.Notification(msg, pid));
break; break;
case 'B': // Binary Data Transfer case 'B': // Binary Data Transfer
receiveTuple(true); receiveTuple(true);
......
...@@ -6,6 +6,7 @@ import java.net.ConnectException; ...@@ -6,6 +6,7 @@ import java.net.ConnectException;
import java.sql.*; import java.sql.*;
import java.util.*; import java.util.*;
import org.postgresql.Driver; import org.postgresql.Driver;
import org.postgresql.PGNotification;
import org.postgresql.PG_Stream; import org.postgresql.PG_Stream;
import org.postgresql.core.*; import org.postgresql.core.*;
import org.postgresql.fastpath.Fastpath; import org.postgresql.fastpath.Fastpath;
...@@ -13,7 +14,7 @@ import org.postgresql.largeobject.LargeObjectManager; ...@@ -13,7 +14,7 @@ import org.postgresql.largeobject.LargeObjectManager;
import org.postgresql.util.*; import org.postgresql.util.*;
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Connection.java,v 1.6 2002/09/01 23:56:13 davec Exp $ /* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Connection.java,v 1.7 2002/09/02 03:07:36 barry Exp $
* This class defines methods of the jdbc1 specification. This class is * This class defines methods of the jdbc1 specification. This class is
* extended by org.postgresql.jdbc2.AbstractJdbc2Connection which adds the jdbc2 * extended by org.postgresql.jdbc2.AbstractJdbc2Connection which adds the jdbc2
* methods. The real Connection class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Connection * methods. The real Connection class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Connection
...@@ -34,6 +35,8 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec ...@@ -34,6 +35,8 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec
protected int pid; protected int pid;
protected int ckey; protected int ckey;
private Vector m_notifications;
/* /*
The encoding to use for this connection. The encoding to use for this connection.
*/ */
...@@ -1309,7 +1312,22 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec ...@@ -1309,7 +1312,22 @@ public abstract class AbstractJdbc1Connection implements org.postgresql.PGConnec
Types.TIMESTAMP, Types.TIMESTAMP, Types.TIMESTAMP Types.TIMESTAMP, Types.TIMESTAMP, Types.TIMESTAMP
}; };
//Methods to support postgres notifications
public void addNotification(org.postgresql.PGNotification p_notification) {
if (m_notifications == null)
m_notifications = new Vector();
m_notifications.addElement(p_notification);
}
public PGNotification[] getNotifications() {
PGNotification[] l_return = null;
if (m_notifications != null) {
l_return = new PGNotification[m_notifications.size()];
m_notifications.copyInto(l_return);
}
m_notifications = null;
return l_return;
}
} }
...@@ -13,7 +13,7 @@ import org.postgresql.largeobject.*; ...@@ -13,7 +13,7 @@ import org.postgresql.largeobject.*;
import org.postgresql.util.PGbytea; import org.postgresql.util.PGbytea;
import org.postgresql.util.PSQLException; import org.postgresql.util.PSQLException;
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1ResultSet.java,v 1.4 2002/08/16 17:51:38 barry Exp $ /* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1ResultSet.java,v 1.5 2002/09/02 03:07:36 barry Exp $
* This class defines methods of the jdbc1 specification. This class is * This class defines methods of the jdbc1 specification. This class is
* extended by org.postgresql.jdbc2.AbstractJdbc2ResultSet which adds the jdbc2 * extended by org.postgresql.jdbc2.AbstractJdbc2ResultSet which adds the jdbc2
* methods. The real ResultSet class (for jdbc1) is org.postgresql.jdbc1.Jdbc1ResultSet * methods. The real ResultSet class (for jdbc1) is org.postgresql.jdbc1.Jdbc1ResultSet
...@@ -934,6 +934,15 @@ public abstract class AbstractJdbc1ResultSet ...@@ -934,6 +934,15 @@ public abstract class AbstractJdbc1ResultSet
} }
else else
{ {
if (slen == 8 && s.equals("infinity"))
//java doesn't have a concept of postgres's infinity
//so set to an arbitrary future date
s = "9999-01-01";
if (slen == 9 && s.equals("-infinity"))
//java doesn't have a concept of postgres's infinity
//so set to an arbitrary old date
s = "0001-01-01";
// We must just have a date. This case is // We must just have a date. This case is
// needed if this method is called on a date // needed if this method is called on a date
// column // column
......
...@@ -8,7 +8,7 @@ import java.util.Vector; ...@@ -8,7 +8,7 @@ import java.util.Vector;
import org.postgresql.largeobject.*; import org.postgresql.largeobject.*;
import org.postgresql.util.PSQLException; import org.postgresql.util.PSQLException;
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2Statement.java,v 1.4 2002/08/23 20:45:49 barry Exp $ /* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2Statement.java,v 1.5 2002/09/02 03:07:36 barry Exp $
* This class defines methods of the jdbc2 specification. This class extends * This class defines methods of the jdbc2 specification. This class extends
* org.postgresql.jdbc1.AbstractJdbc1Statement which provides the jdbc1 * org.postgresql.jdbc1.AbstractJdbc1Statement which provides the jdbc1
* methods. The real Statement class (for jdbc2) is org.postgresql.jdbc2.Jdbc2Statement * methods. The real Statement class (for jdbc2) is org.postgresql.jdbc2.Jdbc2Statement
...@@ -172,23 +172,23 @@ public abstract class AbstractJdbc2Statement extends org.postgresql.jdbc1.Abstra ...@@ -172,23 +172,23 @@ public abstract class AbstractJdbc2Statement extends org.postgresql.jdbc1.Abstra
public void setBlob(int i, Blob x) throws SQLException public void setBlob(int i, Blob x) throws SQLException
{ {
InputStream l_inStream = x.getBinaryStream(); InputStream l_inStream = x.getBinaryStream();
int l_length = (int) x.length();
LargeObjectManager lom = connection.getLargeObjectAPI(); LargeObjectManager lom = connection.getLargeObjectAPI();
int oid = lom.create(); int oid = lom.create();
LargeObject lob = lom.open(oid); LargeObject lob = lom.open(oid);
OutputStream los = lob.getOutputStream(); OutputStream los = lob.getOutputStream();
byte[] buf = new byte[4096];
try try
{ {
// could be buffered, but then the OutputStream returned by LargeObject // could be buffered, but then the OutputStream returned by LargeObject
// is buffered internally anyhow, so there would be no performance // is buffered internally anyhow, so there would be no performance
// boost gained, if anything it would be worse! // boost gained, if anything it would be worse!
int c = l_inStream.read(); int bytesRemaining = (int)x.length();
int p = 0; int numRead = l_inStream.read(buf,0,Math.min(buf.length,bytesRemaining));
while (c > -1 && p < l_length) while (numRead != -1 && bytesRemaining > 0)
{ {
los.write(c); bytesRemaining -= numRead;
c = l_inStream.read(); los.write(buf,0,numRead);
p++; numRead = l_inStream.read(buf,0,Math.min(buf.length,bytesRemaining));
} }
los.close(); los.close();
} }
......
...@@ -88,6 +88,9 @@ public class Array implements java.sql.Array ...@@ -88,6 +88,9 @@ public class Array implements java.sql.Array
boolean insideString = false; boolean insideString = false;
for ( int i = 0; i < chars.length; i++ ) for ( int i = 0; i < chars.length; i++ )
{ {
if ( chars[i] == '\\' )
//escape character that we need to skip
i++;
if ( chars[i] == '{' ) if ( chars[i] == '{' )
{ {
if ( foundOpen ) // Only supports 1-D arrays for now if ( foundOpen ) // Only supports 1-D arrays for now
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment