Commit 839b9bc0 authored by Barry Lind's avatar Barry Lind

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
parent ffb8f738
...@@ -11,7 +11,7 @@ import org.postgresql.util.*; ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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,29 +822,29 @@ public abstract class Connection ...@@ -822,29 +822,29 @@ 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;
} }
/** /**
* You can call this method to try to change the transaction * You can call this method to try to change the transaction
* isolation level using one of the TRANSACTION_* values. * isolation level using one of the TRANSACTION_* values.
* *
* <B>Note:</B> setTransactionIsolation cannot be called while * <B>Note:</B> setTransactionIsolation cannot be called while
* in the middle of a transaction * in the middle of a transaction
* *
...@@ -855,32 +855,32 @@ public abstract class Connection ...@@ -855,32 +855,32 @@ 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.
//When we decide to drop support for servers older than 7.1 //When we decide to drop support for servers older than 7.1
//this can be simplified //this can be simplified
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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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
...@@ -1069,4 +1069,4 @@ public abstract class Connection ...@@ -1069,4 +1069,4 @@ public abstract class Connection
} }
} }
...@@ -18,6 +18,7 @@ public abstract class ResultSet ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -172,7 +174,7 @@ public abstract class ResultSet
*/ */
public int getInsertedOID() public int getInsertedOID()
{ {
return insertOID; return insertOID;
} }
/** /**
......
...@@ -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.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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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);
} }
} }
} }
...@@ -17,7 +17,7 @@ import org.postgresql.largeobject.*; ...@@ -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 ...@@ -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);
} }
......
...@@ -70,9 +70,9 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu ...@@ -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 ...@@ -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 ...@@ -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));
......
...@@ -17,7 +17,7 @@ import org.postgresql.largeobject.*; ...@@ -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 ...@@ -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);
} }
// ***************** // *****************
...@@ -296,9 +296,9 @@ public class Connection extends org.postgresql.Connection implements java.sql.Co ...@@ -296,9 +296,9 @@ public class Connection extends org.postgresql.Connection implements java.sql.Co
"date", "date",
"time", "time",
"abstime","timestamp", "abstime","timestamp",
"_bool", "_char", "_int2", "_int4", "_text", "_bool", "_char", "_int2", "_int4", "_text",
"_oid", "_varchar", "_int8", "_float4", "_float8", "_oid", "_varchar", "_int8", "_float4", "_float8",
"_abstime", "_date", "_time", "_timestamp", "_numeric", "_abstime", "_date", "_time", "_timestamp", "_numeric",
"_bytea" "_bytea"
}; };
...@@ -324,8 +324,8 @@ public class Connection extends org.postgresql.Connection implements java.sql.Co ...@@ -324,8 +324,8 @@ public class Connection extends org.postgresql.Connection implements java.sql.Co
Types.DATE, Types.DATE,
Types.TIME, Types.TIME,
Types.TIMESTAMP,Types.TIMESTAMP, Types.TIMESTAMP,Types.TIMESTAMP,
Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY,
Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY,
Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY,
Types.ARRAY Types.ARRAY
}; };
......
...@@ -74,9 +74,9 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu ...@@ -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 ...@@ -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 ...@@ -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));
......
...@@ -40,9 +40,9 @@ public class UpdateableResultSet extends org.postgresql.jdbc2.ResultSet ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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();
......
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