1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-31 22:04:40 +03:00

This patch fixes a bug introduced in the jdbc bytea support patch.

That patch broke the ability to read data from binary cursors.
--Barry Lind
 Modified Files:
 	pgsql/src/interfaces/jdbc/org/postgresql/Connection.java
 	pgsql/src/interfaces/jdbc/org/postgresql/ResultSet.java
 	pgsql/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java
 	pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Connection.java
 	pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/ResultSet.java
 	pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java
 	pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java
 	pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/UpdateableResultSet.java
This commit is contained in:
Barry Lind
2001-10-09 20:47:35 +00:00
parent ffb8f73890
commit 839b9bc011
8 changed files with 446 additions and 437 deletions

View File

@ -11,7 +11,7 @@ import org.postgresql.util.*;
import org.postgresql.core.*; import org.postgresql.core.*;
/** /**
* $Id: Connection.java,v 1.29 2001/09/10 15:07:05 momjian Exp $ * $Id: Connection.java,v 1.30 2001/10/09 20:47:35 barry Exp $
* *
* This abstract class is used by org.postgresql.Driver to open either the JDBC1 or * This abstract class is used by org.postgresql.Driver to open either the JDBC1 or
* JDBC2 versions of the Connection class. * JDBC2 versions of the Connection class.
@ -130,104 +130,104 @@ public abstract class Connection
// Now make the initial connection // Now make the initial connection
try try
{ {
pg_stream = new PG_Stream(host, port); pg_stream = new PG_Stream(host, port);
} catch (ConnectException cex) { } catch (ConnectException cex) {
// Added by Peter Mount <peter@retep.org.uk> // Added by Peter Mount <peter@retep.org.uk>
// ConnectException is thrown when the connection cannot be made. // ConnectException is thrown when the connection cannot be made.
// we trap this an return a more meaningful message for the end user // we trap this an return a more meaningful message for the end user
throw new PSQLException ("postgresql.con.refused"); throw new PSQLException ("postgresql.con.refused");
} catch (IOException e) { } catch (IOException e) {
throw new PSQLException ("postgresql.con.failed",e); throw new PSQLException ("postgresql.con.failed",e);
} }
// Now we need to construct and send a startup packet // Now we need to construct and send a startup packet
try try
{ {
// Ver 6.3 code // Ver 6.3 code
pg_stream.SendInteger(4+4+SM_DATABASE+SM_USER+SM_OPTIONS+SM_UNUSED+SM_TTY,4); pg_stream.SendInteger(4+4+SM_DATABASE+SM_USER+SM_OPTIONS+SM_UNUSED+SM_TTY,4);
pg_stream.SendInteger(PG_PROTOCOL_LATEST_MAJOR,2); pg_stream.SendInteger(PG_PROTOCOL_LATEST_MAJOR,2);
pg_stream.SendInteger(PG_PROTOCOL_LATEST_MINOR,2); pg_stream.SendInteger(PG_PROTOCOL_LATEST_MINOR,2);
pg_stream.Send(database.getBytes(),SM_DATABASE); pg_stream.Send(database.getBytes(),SM_DATABASE);
// This last send includes the unused fields // This last send includes the unused fields
pg_stream.Send(PG_USER.getBytes(),SM_USER+SM_OPTIONS+SM_UNUSED+SM_TTY); pg_stream.Send(PG_USER.getBytes(),SM_USER+SM_OPTIONS+SM_UNUSED+SM_TTY);
// now flush the startup packets to the backend // now flush the startup packets to the backend
pg_stream.flush(); pg_stream.flush();
// Now get the response from the backend, either an error message // Now get the response from the backend, either an error message
// or an authentication request // or an authentication request
int areq = -1; // must have a value here int areq = -1; // must have a value here
do { do {
int beresp = pg_stream.ReceiveChar(); int beresp = pg_stream.ReceiveChar();
switch(beresp) switch(beresp)
{ {
case 'E': case 'E':
// An error occured, so pass the error message to the // An error occured, so pass the error message to the
// user. // user.
// //
// The most common one to be thrown here is: // The most common one to be thrown here is:
// "User authentication failed" // "User authentication failed"
// //
throw new SQLException(pg_stream.ReceiveString(encoding)); throw new SQLException(pg_stream.ReceiveString(encoding));
case 'R': case 'R':
// Get the type of request // Get the type of request
areq = pg_stream.ReceiveIntegerR(4); areq = pg_stream.ReceiveIntegerR(4);
// Get the password salt if there is one // Get the password salt if there is one
if(areq == AUTH_REQ_CRYPT) { if(areq == AUTH_REQ_CRYPT) {
byte[] rst = new byte[2]; byte[] rst = new byte[2];
rst[0] = (byte)pg_stream.ReceiveChar(); rst[0] = (byte)pg_stream.ReceiveChar();
rst[1] = (byte)pg_stream.ReceiveChar(); rst[1] = (byte)pg_stream.ReceiveChar();
salt = new String(rst,0,2); salt = new String(rst,0,2);
DriverManager.println("Salt="+salt); DriverManager.println("Salt="+salt);
} }
// now send the auth packet // now send the auth packet
switch(areq) switch(areq)
{ {
case AUTH_REQ_OK: case AUTH_REQ_OK:
break; break;
case AUTH_REQ_KRB4: case AUTH_REQ_KRB4:
DriverManager.println("postgresql: KRB4"); DriverManager.println("postgresql: KRB4");
throw new PSQLException("postgresql.con.kerb4"); throw new PSQLException("postgresql.con.kerb4");
case AUTH_REQ_KRB5: case AUTH_REQ_KRB5:
DriverManager.println("postgresql: KRB5"); DriverManager.println("postgresql: KRB5");
throw new PSQLException("postgresql.con.kerb5"); throw new PSQLException("postgresql.con.kerb5");
case AUTH_REQ_PASSWORD: case AUTH_REQ_PASSWORD:
DriverManager.println("postgresql: PASSWORD"); DriverManager.println("postgresql: PASSWORD");
pg_stream.SendInteger(5+PG_PASSWORD.length(),4); pg_stream.SendInteger(5+PG_PASSWORD.length(),4);
pg_stream.Send(PG_PASSWORD.getBytes()); pg_stream.Send(PG_PASSWORD.getBytes());
pg_stream.SendInteger(0,1); pg_stream.SendInteger(0,1);
pg_stream.flush(); pg_stream.flush();
break; break;
case AUTH_REQ_CRYPT: case AUTH_REQ_CRYPT:
DriverManager.println("postgresql: CRYPT"); DriverManager.println("postgresql: CRYPT");
String crypted = UnixCrypt.crypt(salt,PG_PASSWORD); String crypted = UnixCrypt.crypt(salt,PG_PASSWORD);
pg_stream.SendInteger(5+crypted.length(),4); pg_stream.SendInteger(5+crypted.length(),4);
pg_stream.Send(crypted.getBytes()); pg_stream.Send(crypted.getBytes());
pg_stream.SendInteger(0,1); pg_stream.SendInteger(0,1);
pg_stream.flush(); pg_stream.flush();
break; break;
default: default:
throw new PSQLException("postgresql.con.auth",new Integer(areq)); throw new PSQLException("postgresql.con.auth",new Integer(areq));
} }
break; break;
default: default:
throw new PSQLException("postgresql.con.authfail"); throw new PSQLException("postgresql.con.authfail");
} }
} while(areq != AUTH_REQ_OK); } while(areq != AUTH_REQ_OK);
} catch (IOException e) { } catch (IOException e) {
throw new PSQLException("postgresql.con.failed",e); throw new PSQLException("postgresql.con.failed",e);
} }
// As of protocol version 2.0, we should now receive the cancellation key and the pid // As of protocol version 2.0, we should now receive the cancellation key and the pid
@ -237,8 +237,8 @@ public abstract class Connection
pid = pg_stream.ReceiveInteger(4); pid = pg_stream.ReceiveInteger(4);
ckey = pg_stream.ReceiveInteger(4); ckey = pg_stream.ReceiveInteger(4);
break; break;
case 'E': case 'E':
case 'N': case 'N':
throw new SQLException(pg_stream.ReceiveString(encoding)); throw new SQLException(pg_stream.ReceiveString(encoding));
default: default:
throw new PSQLException("postgresql.con.setup"); throw new PSQLException("postgresql.con.setup");
@ -248,9 +248,9 @@ public abstract class Connection
beresp = pg_stream.ReceiveChar(); beresp = pg_stream.ReceiveChar();
switch(beresp) { switch(beresp) {
case 'Z': case 'Z':
break; break;
case 'E': case 'E':
case 'N': case 'N':
throw new SQLException(pg_stream.ReceiveString(encoding)); throw new SQLException(pg_stream.ReceiveString(encoding));
default: default:
throw new PSQLException("postgresql.con.setup"); throw new PSQLException("postgresql.con.setup");
@ -264,16 +264,16 @@ public abstract class Connection
// used, so we denote this with 'UNKNOWN'. // used, so we denote this with 'UNKNOWN'.
final String encodingQuery = final String encodingQuery =
"case when pg_encoding_to_char(1) = 'SQL_ASCII' then 'UNKNOWN' else getdatabaseencoding() end"; "case when pg_encoding_to_char(1) = 'SQL_ASCII' then 'UNKNOWN' else getdatabaseencoding() end";
// Set datestyle and fetch db encoding in a single call, to avoid making // Set datestyle and fetch db encoding in a single call, to avoid making
// more than one round trip to the backend during connection startup. // more than one round trip to the backend during connection startup.
java.sql.ResultSet resultSet = java.sql.ResultSet resultSet =
ExecSQL("set datestyle to 'ISO'; select version(), " + encodingQuery + ";"); ExecSQL("set datestyle to 'ISO'; select version(), " + encodingQuery + ";");
if (! resultSet.next()) { if (! resultSet.next()) {
throw new PSQLException("postgresql.con.failed", "failed getting backend encoding"); throw new PSQLException("postgresql.con.failed", "failed getting backend encoding");
} }
String version = resultSet.getString(1); String version = resultSet.getString(1);
dbVersionNumber = extractVersionNumber(version); dbVersionNumber = extractVersionNumber(version);
@ -299,28 +299,28 @@ public abstract class Connection
*/ */
public void addWarning(String msg) public void addWarning(String msg)
{ {
DriverManager.println(msg); DriverManager.println(msg);
// Add the warning to the chain // Add the warning to the chain
if(firstWarning!=null) if(firstWarning!=null)
firstWarning.setNextWarning(new SQLWarning(msg)); firstWarning.setNextWarning(new SQLWarning(msg));
else else
firstWarning = new SQLWarning(msg); firstWarning = new SQLWarning(msg);
// Now check for some specific messages // Now check for some specific messages
// This is obsolete in 6.5, but I've left it in here so if we need to use this // This is obsolete in 6.5, but I've left it in here so if we need to use this
// technique again, we'll know where to place it. // technique again, we'll know where to place it.
// //
// This is generated by the SQL "show datestyle" // This is generated by the SQL "show datestyle"
//if(msg.startsWith("NOTICE:") && msg.indexOf("DateStyle")>0) { //if(msg.startsWith("NOTICE:") && msg.indexOf("DateStyle")>0) {
//// 13 is the length off "DateStyle is " //// 13 is the length off "DateStyle is "
//msg = msg.substring(msg.indexOf("DateStyle is ")+13); //msg = msg.substring(msg.indexOf("DateStyle is ")+13);
// //
//for(int i=0;i<dateStyles.length;i+=2) //for(int i=0;i<dateStyles.length;i+=2)
//if(msg.startsWith(dateStyles[i])) //if(msg.startsWith(dateStyles[i]))
//currentDateStyle=i+1; // this is the index of the format //currentDateStyle=i+1; // this is the index of the format
//} //}
} }
/** /**
@ -353,7 +353,7 @@ public abstract class Connection
*/ */
public java.sql.ResultSet ExecSQL(String sql, java.sql.Statement stat) throws SQLException public java.sql.ResultSet ExecSQL(String sql, java.sql.Statement stat) throws SQLException
{ {
return new QueryExecutor(sql, stat, pg_stream, this).execute(); return new QueryExecutor(sql, stat, pg_stream, this).execute();
} }
/** /**
@ -371,7 +371,7 @@ public abstract class Connection
*/ */
public void setCursorName(String cursor) throws SQLException public void setCursorName(String cursor) throws SQLException
{ {
this.cursor = cursor; this.cursor = cursor;
} }
/** /**
@ -382,7 +382,7 @@ public abstract class Connection
*/ */
public String getCursorName() throws SQLException public String getCursorName() throws SQLException
{ {
return cursor; return cursor;
} }
/** /**
@ -396,7 +396,7 @@ public abstract class Connection
*/ */
public String getURL() throws SQLException public String getURL() throws SQLException
{ {
return this_url; return this_url;
} }
/** /**
@ -408,7 +408,7 @@ public abstract class Connection
*/ */
public String getUserName() throws SQLException public String getUserName() throws SQLException
{ {
return PG_USER; return PG_USER;
} }
/** /**
@ -442,9 +442,9 @@ public abstract class Connection
*/ */
public Fastpath getFastpathAPI() throws SQLException public Fastpath getFastpathAPI() throws SQLException
{ {
if(fastpath==null) if(fastpath==null)
fastpath = new Fastpath(this,pg_stream); fastpath = new Fastpath(this,pg_stream);
return fastpath; return fastpath;
} }
// This holds a reference to the Fastpath API if already open // This holds a reference to the Fastpath API if already open
@ -471,9 +471,9 @@ public abstract class Connection
*/ */
public LargeObjectManager getLargeObjectAPI() throws SQLException public LargeObjectManager getLargeObjectAPI() throws SQLException
{ {
if(largeobject==null) if(largeobject==null)
largeobject = new LargeObjectManager(this); largeobject = new LargeObjectManager(this);
return largeobject; return largeobject;
} }
// This holds a reference to the LargeObject API if already open // This holds a reference to the LargeObject API if already open
@ -500,46 +500,46 @@ public abstract class Connection
*/ */
public Object getObject(String type,String value) throws SQLException public Object getObject(String type,String value) throws SQLException
{ {
try { try {
Object o = objectTypes.get(type); Object o = objectTypes.get(type);
// If o is null, then the type is unknown, so check to see if type // If o is null, then the type is unknown, so check to see if type
// is an actual table name. If it does, see if a Class is known that // is an actual table name. If it does, see if a Class is known that
// can handle it // can handle it
if(o == null) { if(o == null) {
Serialize ser = new Serialize(this,type); Serialize ser = new Serialize(this,type);
objectTypes.put(type,ser); objectTypes.put(type,ser);
return ser.fetch(Integer.parseInt(value)); return ser.fetch(Integer.parseInt(value));
} }
// If o is not null, and it is a String, then its a class name that // If o is not null, and it is a String, then its a class name that
// extends PGobject. // extends PGobject.
// //
// This is used to implement the org.postgresql unique types (like lseg, // This is used to implement the org.postgresql unique types (like lseg,
// point, etc). // point, etc).
if(o instanceof String) { if(o instanceof String) {
// 6.3 style extending PG_Object // 6.3 style extending PG_Object
PGobject obj = null; PGobject obj = null;
obj = (PGobject)(Class.forName((String)o).newInstance()); obj = (PGobject)(Class.forName((String)o).newInstance());
obj.setType(type); obj.setType(type);
obj.setValue(value); obj.setValue(value);
return (Object)obj; return (Object)obj;
} else { } else {
// If it's an object, it should be an instance of our Serialize class // If it's an object, it should be an instance of our Serialize class
// If so, then call it's fetch method. // If so, then call it's fetch method.
if(o instanceof Serialize) if(o instanceof Serialize)
return ((Serialize)o).fetch(Integer.parseInt(value)); return ((Serialize)o).fetch(Integer.parseInt(value));
} }
} catch(SQLException sx) { } catch(SQLException sx) {
// rethrow the exception. Done because we capture any others next // rethrow the exception. Done because we capture any others next
sx.fillInStackTrace(); sx.fillInStackTrace();
throw sx; throw sx;
} catch(Exception ex) { } catch(Exception ex) {
throw new PSQLException("postgresql.con.creobj",type,ex); throw new PSQLException("postgresql.con.creobj",type,ex);
} }
// should never be reached // should never be reached
return null; return null;
} }
/** /**
@ -551,34 +551,34 @@ public abstract class Connection
*/ */
public int putObject(Object o) throws SQLException public int putObject(Object o) throws SQLException
{ {
try { try {
String type = o.getClass().getName(); String type = o.getClass().getName();
Object x = objectTypes.get(type); Object x = objectTypes.get(type);
// If x is null, then the type is unknown, so check to see if type // If x is null, then the type is unknown, so check to see if type
// is an actual table name. If it does, see if a Class is known that // is an actual table name. If it does, see if a Class is known that
// can handle it // can handle it
if(x == null) { if(x == null) {
Serialize ser = new Serialize(this,type); Serialize ser = new Serialize(this,type);
objectTypes.put(type,ser); objectTypes.put(type,ser);
return ser.store(o); return ser.store(o);
} }
// If it's an object, it should be an instance of our Serialize class // If it's an object, it should be an instance of our Serialize class
// If so, then call it's fetch method. // If so, then call it's fetch method.
if(x instanceof Serialize) if(x instanceof Serialize)
return ((Serialize)x).store(o); return ((Serialize)x).store(o);
// Thow an exception because the type is unknown // Thow an exception because the type is unknown
throw new PSQLException("postgresql.con.strobj"); throw new PSQLException("postgresql.con.strobj");
} catch(SQLException sx) { } catch(SQLException sx) {
// rethrow the exception. Done because we capture any others next // rethrow the exception. Done because we capture any others next
sx.fillInStackTrace(); sx.fillInStackTrace();
throw sx; throw sx;
} catch(Exception ex) { } catch(Exception ex) {
throw new PSQLException("postgresql.con.strobjex",ex); throw new PSQLException("postgresql.con.strobjex",ex);
} }
} }
/** /**
@ -603,7 +603,7 @@ public abstract class Connection
*/ */
public void addDataType(String type,String name) public void addDataType(String type,String name)
{ {
objectTypes.put(type,name); objectTypes.put(type,name);
} }
// This holds the available types // This holds the available types
@ -615,21 +615,21 @@ public abstract class Connection
// the full class name of the handling class. // the full class name of the handling class.
// //
private static final String defaultObjectTypes[][] = { private static final String defaultObjectTypes[][] = {
{"box", "org.postgresql.geometric.PGbox"}, {"box", "org.postgresql.geometric.PGbox"},
{"circle", "org.postgresql.geometric.PGcircle"}, {"circle", "org.postgresql.geometric.PGcircle"},
{"line", "org.postgresql.geometric.PGline"}, {"line", "org.postgresql.geometric.PGline"},
{"lseg", "org.postgresql.geometric.PGlseg"}, {"lseg", "org.postgresql.geometric.PGlseg"},
{"path", "org.postgresql.geometric.PGpath"}, {"path", "org.postgresql.geometric.PGpath"},
{"point", "org.postgresql.geometric.PGpoint"}, {"point", "org.postgresql.geometric.PGpoint"},
{"polygon", "org.postgresql.geometric.PGpolygon"}, {"polygon", "org.postgresql.geometric.PGpolygon"},
{"money", "org.postgresql.util.PGmoney"} {"money", "org.postgresql.util.PGmoney"}
}; };
// This initialises the objectTypes hashtable // This initialises the objectTypes hashtable
private void initObjectTypes() private void initObjectTypes()
{ {
for(int i=0;i<defaultObjectTypes.length;i++) for(int i=0;i<defaultObjectTypes.length;i++)
objectTypes.put(defaultObjectTypes[i][0],defaultObjectTypes[i][1]); objectTypes.put(defaultObjectTypes[i][0],defaultObjectTypes[i][1]);
} }
// These are required by other common classes // These are required by other common classes
@ -639,7 +639,7 @@ public abstract class Connection
* This returns a resultset. It must be overridden, so that the correct * This returns a resultset. It must be overridden, so that the correct
* version (from jdbc1 or jdbc2) are returned. * version (from jdbc1 or jdbc2) are returned.
*/ */
public abstract java.sql.ResultSet getResultSet(org.postgresql.Connection conn,java.sql.Statement stat, Field[] fields, Vector tuples, String status, int updateCount,int insertOID) throws SQLException; public abstract java.sql.ResultSet getResultSet(org.postgresql.Connection conn,java.sql.Statement stat, Field[] fields, Vector tuples, String status, int updateCount,int insertOID, boolean binaryCursor) throws SQLException;
/** /**
* In some cases, it is desirable to immediately release a Connection's * In some cases, it is desirable to immediately release a Connection's
@ -653,14 +653,14 @@ public abstract class Connection
* @exception SQLException if a database access error occurs * @exception SQLException if a database access error occurs
*/ */
public void close() throws SQLException { public void close() throws SQLException {
if (pg_stream != null) { if (pg_stream != null) {
try { try {
pg_stream.SendChar('X'); pg_stream.SendChar('X');
pg_stream.flush(); pg_stream.flush();
pg_stream.close(); pg_stream.close();
} catch (IOException e) {} } catch (IOException e) {}
pg_stream = null; pg_stream = null;
} }
} }
/** /**
@ -674,7 +674,7 @@ public abstract class Connection
* @exception SQLException if a database access error occurs * @exception SQLException if a database access error occurs
*/ */
public String nativeSQL(String sql) throws SQLException { public String nativeSQL(String sql) throws SQLException {
return sql; return sql;
} }
/** /**
@ -688,7 +688,7 @@ public abstract class Connection
* @exception SQLException if a database access error occurs * @exception SQLException if a database access error occurs
*/ */
public SQLWarning getWarnings() throws SQLException { public SQLWarning getWarnings() throws SQLException {
return firstWarning; return firstWarning;
} }
/** /**
@ -698,7 +698,7 @@ public abstract class Connection
* @exception SQLException if a database access error occurs * @exception SQLException if a database access error occurs
*/ */
public void clearWarnings() throws SQLException { public void clearWarnings() throws SQLException {
firstWarning = null; firstWarning = null;
} }
@ -713,7 +713,7 @@ public abstract class Connection
* @exception SQLException if a database access error occurs * @exception SQLException if a database access error occurs
*/ */
public void setReadOnly(boolean readOnly) throws SQLException { public void setReadOnly(boolean readOnly) throws SQLException {
this.readOnly = readOnly; this.readOnly = readOnly;
} }
/** /**
@ -725,7 +725,7 @@ public abstract class Connection
* @exception SQLException if a database access error occurs * @exception SQLException if a database access error occurs
*/ */
public boolean isReadOnly() throws SQLException { public boolean isReadOnly() throws SQLException {
return readOnly; return readOnly;
} }
/** /**
@ -747,19 +747,19 @@ public abstract class Connection
* @exception SQLException if a database access error occurs * @exception SQLException if a database access error occurs
*/ */
public void setAutoCommit(boolean autoCommit) throws SQLException { public void setAutoCommit(boolean autoCommit) throws SQLException {
if (this.autoCommit == autoCommit) if (this.autoCommit == autoCommit)
return; return;
if (autoCommit) if (autoCommit)
ExecSQL("end"); ExecSQL("end");
else { else {
if (haveMinimumServerVersion("7.1")){ if (haveMinimumServerVersion("7.1")){
ExecSQL("begin;"+getIsolationLevelSQL()); ExecSQL("begin;"+getIsolationLevelSQL());
}else{ }else{
ExecSQL("begin"); ExecSQL("begin");
ExecSQL(getIsolationLevelSQL()); ExecSQL(getIsolationLevelSQL());
} }
} }
this.autoCommit = autoCommit; this.autoCommit = autoCommit;
} }
/** /**
@ -770,7 +770,7 @@ public abstract class Connection
* @see setAutoCommit * @see setAutoCommit
*/ */
public boolean getAutoCommit() throws SQLException { public boolean getAutoCommit() throws SQLException {
return this.autoCommit; return this.autoCommit;
} }
/** /**
@ -784,14 +784,14 @@ public abstract class Connection
* @see setAutoCommit * @see setAutoCommit
*/ */
public void commit() throws SQLException { public void commit() throws SQLException {
if (autoCommit) if (autoCommit)
return; return;
if (haveMinimumServerVersion("7.1")){ if (haveMinimumServerVersion("7.1")){
ExecSQL("commit;begin;"+getIsolationLevelSQL()); ExecSQL("commit;begin;"+getIsolationLevelSQL());
}else{ }else{
ExecSQL("commit"); ExecSQL("commit");
ExecSQL("begin"); ExecSQL("begin");
ExecSQL(getIsolationLevelSQL()); ExecSQL(getIsolationLevelSQL());
} }
} }
@ -804,15 +804,15 @@ public abstract class Connection
* @see commit * @see commit
*/ */
public void rollback() throws SQLException { public void rollback() throws SQLException {
if (autoCommit) if (autoCommit)
return; return;
if (haveMinimumServerVersion("7.1")){ if (haveMinimumServerVersion("7.1")){
ExecSQL("rollback; begin;"+getIsolationLevelSQL()); ExecSQL("rollback; begin;"+getIsolationLevelSQL());
}else{ }else{
ExecSQL("rollback"); ExecSQL("rollback");
ExecSQL("begin"); ExecSQL("begin");
ExecSQL(getIsolationLevelSQL()); ExecSQL(getIsolationLevelSQL());
} }
} }
/** /**
@ -822,23 +822,23 @@ public abstract class Connection
* @exception SQLException if a database access error occurs * @exception SQLException if a database access error occurs
*/ */
public int getTransactionIsolation() throws SQLException { public int getTransactionIsolation() throws SQLException {
clearWarnings(); clearWarnings();
ExecSQL("show xactisolevel"); ExecSQL("show xactisolevel");
SQLWarning warning = getWarnings(); SQLWarning warning = getWarnings();
if (warning != null) { if (warning != null) {
String message = warning.getMessage(); String message = warning.getMessage();
clearWarnings(); clearWarnings();
if (message.indexOf("READ COMMITTED") != -1) if (message.indexOf("READ COMMITTED") != -1)
return java.sql.Connection.TRANSACTION_READ_COMMITTED; return java.sql.Connection.TRANSACTION_READ_COMMITTED;
else if (message.indexOf("READ UNCOMMITTED") != -1) else if (message.indexOf("READ UNCOMMITTED") != -1)
return java.sql.Connection.TRANSACTION_READ_UNCOMMITTED; return java.sql.Connection.TRANSACTION_READ_UNCOMMITTED;
else if (message.indexOf("REPEATABLE READ") != -1) else if (message.indexOf("REPEATABLE READ") != -1)
return java.sql.Connection.TRANSACTION_REPEATABLE_READ; return java.sql.Connection.TRANSACTION_REPEATABLE_READ;
else if (message.indexOf("SERIALIZABLE") != -1) else if (message.indexOf("SERIALIZABLE") != -1)
return java.sql.Connection.TRANSACTION_SERIALIZABLE; return java.sql.Connection.TRANSACTION_SERIALIZABLE;
} }
return java.sql.Connection.TRANSACTION_READ_COMMITTED; return java.sql.Connection.TRANSACTION_READ_COMMITTED;
} }
/** /**
@ -855,7 +855,7 @@ public abstract class Connection
* @see java.sql.DatabaseMetaData#supportsTransactionIsolationLevel * @see java.sql.DatabaseMetaData#supportsTransactionIsolationLevel
*/ */
public void setTransactionIsolation(int level) throws SQLException { public void setTransactionIsolation(int level) throws SQLException {
//In 7.1 and later versions of the server it is possible using //In 7.1 and later versions of the server it is possible using
//the "set session" command to set this once for all future txns //the "set session" command to set this once for all future txns
//however in 7.0 and prior versions it is necessary to set it in //however in 7.0 and prior versions it is necessary to set it in
//each transaction, thus adding complexity below. //each transaction, thus adding complexity below.
@ -864,23 +864,23 @@ public abstract class Connection
isolationLevel = level; isolationLevel = level;
String isolationLevelSQL; String isolationLevelSQL;
if (!haveMinimumServerVersion("7.1")) { if (!haveMinimumServerVersion("7.1")) {
isolationLevelSQL = getIsolationLevelSQL(); isolationLevelSQL = getIsolationLevelSQL();
} else { } else {
isolationLevelSQL = "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL "; isolationLevelSQL = "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL ";
switch(isolationLevel) { switch(isolationLevel) {
case java.sql.Connection.TRANSACTION_READ_COMMITTED: case java.sql.Connection.TRANSACTION_READ_COMMITTED:
isolationLevelSQL += "READ COMMITTED"; isolationLevelSQL += "READ COMMITTED";
break; break;
case java.sql.Connection.TRANSACTION_SERIALIZABLE: case java.sql.Connection.TRANSACTION_SERIALIZABLE:
isolationLevelSQL += "SERIALIZABLE"; isolationLevelSQL += "SERIALIZABLE";
break; break;
default: default:
throw new PSQLException("postgresql.con.isolevel", throw new PSQLException("postgresql.con.isolevel",
new Integer(isolationLevel)); new Integer(isolationLevel));
} }
} }
ExecSQL(isolationLevelSQL); ExecSQL(isolationLevelSQL);
} }
/** /**
@ -893,25 +893,25 @@ public abstract class Connection
* servers are dropped * servers are dropped
*/ */
protected String getIsolationLevelSQL() throws SQLException { protected String getIsolationLevelSQL() throws SQLException {
//7.1 and higher servers have a default specified so //7.1 and higher servers have a default specified so
//no additional SQL is required to set the isolation level //no additional SQL is required to set the isolation level
if (haveMinimumServerVersion("7.1")) { if (haveMinimumServerVersion("7.1")) {
return ""; return "";
} }
StringBuffer sb = new StringBuffer("SET TRANSACTION ISOLATION LEVEL"); StringBuffer sb = new StringBuffer("SET TRANSACTION ISOLATION LEVEL");
switch(isolationLevel) { switch(isolationLevel) {
case java.sql.Connection.TRANSACTION_READ_COMMITTED: case java.sql.Connection.TRANSACTION_READ_COMMITTED:
sb.append(" READ COMMITTED"); sb.append(" READ COMMITTED");
break; break;
case java.sql.Connection.TRANSACTION_SERIALIZABLE: case java.sql.Connection.TRANSACTION_SERIALIZABLE:
sb.append(" SERIALIZABLE"); sb.append(" SERIALIZABLE");
break; break;
default: default:
throw new PSQLException("postgresql.con.isolevel",new Integer(isolationLevel)); throw new PSQLException("postgresql.con.isolevel",new Integer(isolationLevel));
} }
return sb.toString(); return sb.toString();
} }
@ -936,7 +936,7 @@ public abstract class Connection
*/ */
public String getCatalog() throws SQLException public String getCatalog() throws SQLException
{ {
return PG_DATABASE; return PG_DATABASE;
} }
/** /**
@ -949,7 +949,7 @@ public abstract class Connection
*/ */
public void finalize() throws Throwable public void finalize() throws Throwable
{ {
close(); close();
} }
private static String extractVersionNumber(String fullVersionString) private static String extractVersionNumber(String fullVersionString)
@ -963,7 +963,7 @@ public abstract class Connection
* Get server version number * Get server version number
*/ */
public String getDBVersionNumber() { public String getDBVersionNumber() {
return dbVersionNumber; return dbVersionNumber;
} }
public boolean haveMinimumServerVersion(String ver) throws SQLException public boolean haveMinimumServerVersion(String ver) throws SQLException

View File

@ -18,6 +18,7 @@ public abstract class ResultSet
protected Vector rows; // The results protected Vector rows; // The results
protected Field fields[]; // The field descriptions protected Field fields[]; // The field descriptions
protected String status; // Status of the result protected String status; // Status of the result
protected boolean binaryCursor = false; // is the data binary or Strings
protected int updateCount; // How many rows did we get back? protected int updateCount; // How many rows did we get back?
protected int insertOID; // The oid of an inserted row protected int insertOID; // The oid of an inserted row
protected int current_row; // Our pointer to where we are at protected int current_row; // Our pointer to where we are at
@ -41,7 +42,7 @@ public abstract class ResultSet
* @param updateCount the number of rows affected by the operation * @param updateCount the number of rows affected by the operation
* @param cursor the positioned update/delete cursor name * @param cursor the positioned update/delete cursor name
*/ */
public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount,int insertOID) public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount,int insertOID, boolean binaryCursor)
{ {
this.connection = conn; this.connection = conn;
this.fields = fields; this.fields = fields;
@ -51,6 +52,7 @@ public abstract class ResultSet
this.insertOID = insertOID; this.insertOID = insertOID;
this.this_row = null; this.this_row = null;
this.current_row = -1; this.current_row = -1;
this.binaryCursor = binaryCursor;
} }
@ -65,10 +67,10 @@ public abstract class ResultSet
* @param updateCount the number of rows affected by the operation * @param updateCount the number of rows affected by the operation
* @param cursor the positioned update/delete cursor name * @param cursor the positioned update/delete cursor name
*/ */
public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount) public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount)
{ {
this(conn,fields,tuples,status,updateCount,0); this(conn,fields,tuples,status,updateCount,0,false);
} }
/** /**
* We at times need to know if the resultSet we are working * We at times need to know if the resultSet we are working
@ -172,7 +174,7 @@ public abstract class ResultSet
*/ */
public int getInsertedOID() public int getInsertedOID()
{ {
return insertOID; return insertOID;
} }
/** /**

View File

@ -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.1 2001/09/06 03:58:59 momjian Exp $ * $Id: QueryExecutor.java,v 1.2 2001/10/09 20:47:35 barry Exp $
*/ */
public class QueryExecutor { public class QueryExecutor {
@ -24,24 +24,25 @@ public class QueryExecutor {
private final org.postgresql.Connection connection; private final org.postgresql.Connection connection;
public QueryExecutor(String sql, public QueryExecutor(String sql,
java.sql.Statement statement, java.sql.Statement statement,
PG_Stream pg_stream, PG_Stream pg_stream,
org.postgresql.Connection connection) org.postgresql.Connection connection)
throws SQLException throws SQLException
{ {
this.sql = sql; this.sql = sql;
this.statement = statement; this.statement = statement;
this.pg_stream = pg_stream; this.pg_stream = pg_stream;
this.connection = connection; this.connection = connection;
if (statement != null) if (statement != null)
maxRows = statement.getMaxRows(); maxRows = statement.getMaxRows();
else else
maxRows = 0; maxRows = 0;
} }
private Field[] fields = null; private Field[] fields = null;
private Vector tuples = new Vector(); private Vector tuples = new Vector();
private boolean binaryCursor = false;
private String status = null; private String status = null;
private int update_count = 1; private int update_count = 1;
private int insert_oid = 0; private int insert_oid = 0;
@ -52,84 +53,83 @@ public class QueryExecutor {
*/ */
public java.sql.ResultSet execute() throws SQLException { public java.sql.ResultSet execute() throws SQLException {
int fqp = 0; int fqp = 0;
boolean hfr = false; boolean hfr = false;
synchronized(pg_stream) { synchronized(pg_stream) {
sendQuery(sql); sendQuery(sql);
while (!hfr || fqp > 0) { while (!hfr || fqp > 0) {
int c = pg_stream.ReceiveChar(); int c = pg_stream.ReceiveChar();
switch (c) switch (c)
{ {
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());
break; break;
case 'B': // Binary Data Transfer case 'B': // Binary Data Transfer
receiveTuple(true); receiveTuple(true);
break; break;
case 'C': // Command Status case 'C': // Command Status
receiveCommandStatus(); receiveCommandStatus();
if (fields != null) if (fields != null)
hfr = true; hfr = true;
else { else {
sendQuery(" "); sendQuery(" ");
fqp++; fqp++;
} }
break; break;
case 'D': // Text Data Transfer case 'D': // Text Data Transfer
receiveTuple(false); receiveTuple(false);
break; break;
case 'E': // Error Message case 'E': // Error Message
throw new SQLException(pg_stream.ReceiveString(connection.getEncoding())); throw new SQLException(pg_stream.ReceiveString(connection.getEncoding()));
case 'I': // Empty Query case 'I': // Empty Query
int t = pg_stream.ReceiveChar(); int t = pg_stream.ReceiveChar();
if (t != 0) if (t != 0)
throw new PSQLException("postgresql.con.garbled"); throw new PSQLException("postgresql.con.garbled");
if (fqp > 0) if (fqp > 0)
fqp--; fqp--;
if (fqp == 0) if (fqp == 0)
hfr = true; hfr = true;
break; break;
case 'N': // Error Notification case 'N': // Error Notification
connection.addWarning(pg_stream.ReceiveString(connection.getEncoding())); connection.addWarning(pg_stream.ReceiveString(connection.getEncoding()));
break; break;
case 'P': // Portal Name case 'P': // Portal Name
String pname = pg_stream.ReceiveString(connection.getEncoding()); String pname = pg_stream.ReceiveString(connection.getEncoding());
break; break;
case 'T': // MetaData Field Description case 'T': // MetaData Field Description
receiveFields(); receiveFields();
break; break;
case 'Z': // backend ready for query, ignore for now :-) case 'Z': // backend ready for query, ignore for now :-)
break; break;
default: default:
throw new PSQLException("postgresql.con.type", throw new PSQLException("postgresql.con.type",
new Character((char) c)); new Character((char) c));
} }
} }
return connection.getResultSet(connection, statement, fields, tuples, status, update_count, insert_oid, binaryCursor);
return connection.getResultSet(connection, statement, fields, tuples, status, update_count, insert_oid); }
}
} }
/** /**
* Send a query to the backend. * Send a query to the backend.
*/ */
private void sendQuery(String query) throws SQLException { private void sendQuery(String query) throws SQLException {
try { try {
pg_stream.SendChar('Q'); pg_stream.SendChar('Q');
pg_stream.Send(connection.getEncoding().encode(query)); pg_stream.Send(connection.getEncoding().encode(query));
pg_stream.SendChar(0); pg_stream.SendChar(0);
pg_stream.flush(); pg_stream.flush();
} catch (IOException e) { } catch (IOException e) {
throw new PSQLException("postgresql.con.ioerror", e); throw new PSQLException("postgresql.con.ioerror", e);
} }
} }
/** /**
@ -138,11 +138,12 @@ public class QueryExecutor {
* @param isBinary set if the tuple should be treated as binary data * @param isBinary set if the tuple should be treated as binary data
*/ */
private void receiveTuple(boolean isBinary) throws SQLException { private void receiveTuple(boolean isBinary) throws SQLException {
if (fields == null) if (fields == null)
throw new PSQLException("postgresql.con.tuple"); throw new PSQLException("postgresql.con.tuple");
Object tuple = pg_stream.ReceiveTuple(fields.length, isBinary); Object tuple = pg_stream.ReceiveTuple(fields.length, isBinary);
if (maxRows == 0 || tuples.size() < maxRows) if (isBinary) binaryCursor = true;
tuples.addElement(tuple); if (maxRows == 0 || tuples.size() < maxRows)
tuples.addElement(tuple);
} }
/** /**
@ -150,38 +151,38 @@ public class QueryExecutor {
*/ */
private void receiveCommandStatus() throws SQLException { private void receiveCommandStatus() throws SQLException {
status = pg_stream.ReceiveString(connection.getEncoding()); status = pg_stream.ReceiveString(connection.getEncoding());
try { try {
// Now handle the update count correctly. // Now handle the update count correctly.
if (status.startsWith("INSERT") || status.startsWith("UPDATE") || status.startsWith("DELETE") || status.startsWith("MOVE")) { if (status.startsWith("INSERT") || status.startsWith("UPDATE") || status.startsWith("DELETE") || status.startsWith("MOVE")) {
update_count = Integer.parseInt(status.substring(1 + status.lastIndexOf(' '))); update_count = Integer.parseInt(status.substring(1 + status.lastIndexOf(' ')));
} }
if (status.startsWith("INSERT")) { if (status.startsWith("INSERT")) {
insert_oid = Integer.parseInt(status.substring(1 + status.indexOf(' '), insert_oid = Integer.parseInt(status.substring(1 + status.indexOf(' '),
status.lastIndexOf(' '))); status.lastIndexOf(' ')));
} }
} catch (NumberFormatException nfe) { } catch (NumberFormatException nfe) {
throw new PSQLException("postgresql.con.fathom", status); throw new PSQLException("postgresql.con.fathom", status);
} }
} }
/** /**
* Receive the field descriptions from the back end. * Receive the field descriptions from the back end.
*/ */
private void receiveFields() throws SQLException { private void receiveFields() throws SQLException {
if (fields != null) if (fields != null)
throw new PSQLException("postgresql.con.multres"); throw new PSQLException("postgresql.con.multres");
int size = pg_stream.ReceiveIntegerR(2); int size = pg_stream.ReceiveIntegerR(2);
fields = new Field[size]; fields = new Field[size];
for (int i = 0; i < fields.length; i++) { for (int i = 0; i < fields.length; i++) {
String typeName = pg_stream.ReceiveString(connection.getEncoding()); String typeName = pg_stream.ReceiveString(connection.getEncoding());
int typeOid = pg_stream.ReceiveIntegerR(4); int typeOid = pg_stream.ReceiveIntegerR(4);
int typeLength = pg_stream.ReceiveIntegerR(2); int typeLength = pg_stream.ReceiveIntegerR(2);
int typeModifier = pg_stream.ReceiveIntegerR(4); int typeModifier = pg_stream.ReceiveIntegerR(4);
fields[i] = new Field(connection, typeName, typeOid, typeLength, typeModifier); fields[i] = new Field(connection, typeName, typeOid, typeLength, typeModifier);
} }
} }
} }

View File

@ -17,7 +17,7 @@ import org.postgresql.largeobject.*;
import org.postgresql.util.*; import org.postgresql.util.*;
/** /**
* $Id: Connection.java,v 1.10 2001/09/10 15:07:05 momjian Exp $ * $Id: Connection.java,v 1.11 2001/10/09 20:47:35 barry Exp $
* *
* A Connection represents a session with a specific database. Within the * A Connection represents a session with a specific database. Within the
* context of a Connection, SQL statements are executed and results are * context of a Connection, SQL statements are executed and results are
@ -131,10 +131,10 @@ public class Connection extends org.postgresql.Connection implements java.sql.Co
* This overides the method in org.postgresql.Connection and returns a * This overides the method in org.postgresql.Connection and returns a
* ResultSet. * ResultSet.
*/ */
public java.sql.ResultSet getResultSet(org.postgresql.Connection conn,java.sql.Statement stat, Field[] fields, Vector tuples, String status, int updateCount,int insertOID) throws SQLException public java.sql.ResultSet getResultSet(org.postgresql.Connection conn,java.sql.Statement stat, Field[] fields, Vector tuples, String status, int updateCount,int insertOID, boolean binaryCursor) throws SQLException
{ {
// in jdbc1 stat is ignored. // in jdbc1 stat is ignored.
return new org.postgresql.jdbc1.ResultSet((org.postgresql.jdbc1.Connection)conn,fields,tuples,status,updateCount,insertOID); return new org.postgresql.jdbc1.ResultSet((org.postgresql.jdbc1.Connection)conn,fields,tuples,status,updateCount,insertOID,binaryCursor);
} }

View File

@ -70,9 +70,9 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
* @param updateCount the number of rows affected by the operation * @param updateCount the number of rows affected by the operation
* @param cursor the positioned update/delete cursor name * @param cursor the positioned update/delete cursor name
*/ */
public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount,int insertOID) public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount, int insertOID, boolean binaryCursor)
{ {
super(conn,fields,tuples,status,updateCount,insertOID); super(conn,fields,tuples,status,updateCount,insertOID,binaryCursor);
} }
/** /**
@ -86,10 +86,10 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
* @param updateCount the number of rows affected by the operation * @param updateCount the number of rows affected by the operation
* @param cursor the positioned update/delete cursor name * @param cursor the positioned update/delete cursor name
*/ */
public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount) public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount)
{ {
super(conn,fields,tuples,status,updateCount,0); super(conn,fields,tuples,status,updateCount,0,false);
} }
/** /**
* A ResultSet is initially positioned before its first row, * A ResultSet is initially positioned before its first row,
@ -375,6 +375,9 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
if (columnIndex < 1 || columnIndex > fields.length) if (columnIndex < 1 || columnIndex > fields.length)
throw new PSQLException("postgresql.res.colrange"); throw new PSQLException("postgresql.res.colrange");
//If the data is already binary then just return it
if (binaryCursor) return this_row[columnIndex - 1];
if (connection.haveMinimumCompatibleVersion("7.2")) { if (connection.haveMinimumCompatibleVersion("7.2")) {
//Version 7.2 supports the bytea datatype for byte arrays //Version 7.2 supports the bytea datatype for byte arrays
return PGbytea.toBytes(getString(columnIndex)); return PGbytea.toBytes(getString(columnIndex));

View File

@ -17,7 +17,7 @@ import org.postgresql.largeobject.*;
import org.postgresql.util.*; import org.postgresql.util.*;
/** /**
* $Id: Connection.java,v 1.12 2001/09/10 15:07:05 momjian Exp $ * $Id: Connection.java,v 1.13 2001/10/09 20:47:35 barry Exp $
* *
* A Connection represents a session with a specific database. Within the * A Connection represents a session with a specific database. Within the
* context of a Connection, SQL statements are executed and results are * context of a Connection, SQL statements are executed and results are
@ -204,16 +204,16 @@ public class Connection extends org.postgresql.Connection implements java.sql.Co
* This overides the method in org.postgresql.Connection and returns a * This overides the method in org.postgresql.Connection and returns a
* ResultSet. * ResultSet.
*/ */
public java.sql.ResultSet getResultSet(org.postgresql.Connection conn, java.sql.Statement stat,Field[] fields, Vector tuples, String status, int updateCount, int insertOID) throws SQLException public java.sql.ResultSet getResultSet(org.postgresql.Connection conn, java.sql.Statement stat,Field[] fields, Vector tuples, String status, int updateCount, int insertOID, boolean binaryCursor) throws SQLException
{ {
// In 7.1 we now test concurrency to see which class to return. If we are not working with a // In 7.1 we now test concurrency to see which class to return. If we are not working with a
// Statement then default to a normal ResultSet object. // Statement then default to a normal ResultSet object.
if(stat!=null) { if(stat!=null) {
if(stat.getResultSetConcurrency()==java.sql.ResultSet.CONCUR_UPDATABLE) if(stat.getResultSetConcurrency()==java.sql.ResultSet.CONCUR_UPDATABLE)
return new org.postgresql.jdbc2.UpdateableResultSet((org.postgresql.jdbc2.Connection)conn,fields,tuples,status,updateCount,insertOID); return new org.postgresql.jdbc2.UpdateableResultSet((org.postgresql.jdbc2.Connection)conn,fields,tuples,status,updateCount,insertOID,binaryCursor);
} }
return new org.postgresql.jdbc2.ResultSet((org.postgresql.jdbc2.Connection)conn,fields,tuples,status,updateCount,insertOID); return new org.postgresql.jdbc2.ResultSet((org.postgresql.jdbc2.Connection)conn,fields,tuples,status,updateCount,insertOID,binaryCursor);
} }
// ***************** // *****************

View File

@ -74,9 +74,9 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
* @param updateCount the number of rows affected by the operation * @param updateCount the number of rows affected by the operation
* @param cursor the positioned update/delete cursor name * @param cursor the positioned update/delete cursor name
*/ */
public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount,int insertOID) public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount,int insertOID, boolean binaryCursor)
{ {
super(conn,fields,tuples,status,updateCount,insertOID); super(conn,fields,tuples,status,updateCount,insertOID,binaryCursor);
} }
/** /**
@ -90,10 +90,10 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
* @param updateCount the number of rows affected by the operation * @param updateCount the number of rows affected by the operation
* @param cursor the positioned update/delete cursor name * @param cursor the positioned update/delete cursor name
*/ */
public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount) public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount)
{ {
super(conn,fields,tuples,status,updateCount,0); super(conn,fields,tuples,status,updateCount,0,false);
} }
/** /**
* A ResultSet is initially positioned before its first row, * A ResultSet is initially positioned before its first row,
@ -313,6 +313,9 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
if (columnIndex < 1 || columnIndex > fields.length) if (columnIndex < 1 || columnIndex > fields.length)
throw new PSQLException("postgresql.res.colrange"); throw new PSQLException("postgresql.res.colrange");
//If the data is already binary then just return it
if (binaryCursor) return this_row[columnIndex - 1];
if (connection.haveMinimumCompatibleVersion("7.2")) { if (connection.haveMinimumCompatibleVersion("7.2")) {
//Version 7.2 supports the bytea datatype for byte arrays //Version 7.2 supports the bytea datatype for byte arrays
return PGbytea.toBytes(getString(columnIndex)); return PGbytea.toBytes(getString(columnIndex));

View File

@ -40,9 +40,9 @@ public class UpdateableResultSet extends org.postgresql.jdbc2.ResultSet
* @param updateCount the number of rows affected by the operation * @param updateCount the number of rows affected by the operation
* @param cursor the positioned update/delete cursor name * @param cursor the positioned update/delete cursor name
*/ */
public UpdateableResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount,int insertOID) public UpdateableResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount,int insertOID, boolean binaryCursor)
{ {
super(conn,fields,tuples,status,updateCount,insertOID); super(conn,fields,tuples,status,updateCount,insertOID,binaryCursor);
} }
/** /**
@ -56,10 +56,10 @@ public class UpdateableResultSet extends org.postgresql.jdbc2.ResultSet
* @param updateCount the number of rows affected by the operation * @param updateCount the number of rows affected by the operation
* @param cursor the positioned update/delete cursor name * @param cursor the positioned update/delete cursor name
*/ */
public UpdateableResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount) // public UpdateableResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount)
{ // {
super(conn,fields,tuples,status,updateCount,0); // super(conn,fields,tuples,status,updateCount,0,false);
} //}
public void cancelRowUpdates() throws SQLException public void cancelRowUpdates() throws SQLException
{ {
@ -77,7 +77,7 @@ public class UpdateableResultSet extends org.postgresql.jdbc2.ResultSet
{ {
// New in 7.1 - The updateable ResultSet class will now return // New in 7.1 - The updateable ResultSet class will now return
// CONCUR_UPDATEABLE. // CONCUR_UPDATEABLE.
return CONCUR_UPDATABLE; return CONCUR_UPDATABLE;
} }
public void insertRow() throws SQLException public void insertRow() throws SQLException
@ -120,26 +120,26 @@ public class UpdateableResultSet extends org.postgresql.jdbc2.ResultSet
} }
public void updateAsciiStream(int columnIndex, public void updateAsciiStream(int columnIndex,
java.io.InputStream x, java.io.InputStream x,
int length int length
) throws SQLException ) throws SQLException
{ {
// only sub-classes implement CONCUR_UPDATEABLE // only sub-classes implement CONCUR_UPDATEABLE
throw org.postgresql.Driver.notImplemented(); throw org.postgresql.Driver.notImplemented();
} }
public void updateBigDecimal(int columnIndex, public void updateBigDecimal(int columnIndex,
java.math.BigDecimal x java.math.BigDecimal x
) throws SQLException ) throws SQLException
{ {
// only sub-classes implement CONCUR_UPDATEABLE // only sub-classes implement CONCUR_UPDATEABLE
throw org.postgresql.Driver.notImplemented(); throw org.postgresql.Driver.notImplemented();
} }
public void updateBinaryStream(int columnIndex, public void updateBinaryStream(int columnIndex,
java.io.InputStream x, java.io.InputStream x,
int length int length
) throws SQLException ) throws SQLException
{ {
// only sub-classes implement CONCUR_UPDATEABLE // only sub-classes implement CONCUR_UPDATEABLE
throw org.postgresql.Driver.notImplemented(); throw org.postgresql.Driver.notImplemented();
@ -164,9 +164,9 @@ public class UpdateableResultSet extends org.postgresql.jdbc2.ResultSet
} }
public void updateCharacterStream(int columnIndex, public void updateCharacterStream(int columnIndex,
java.io.Reader x, java.io.Reader x,
int length int length
) throws SQLException ) throws SQLException
{ {
// only sub-classes implement CONCUR_UPDATEABLE // only sub-classes implement CONCUR_UPDATEABLE
throw org.postgresql.Driver.notImplemented(); throw org.postgresql.Driver.notImplemented();