Skip to content

Commit 839b9bc

Browse files
author
Barry Lind
committed
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
1 parent ffb8f73 commit 839b9bc

File tree

8 files changed

+480
-471
lines changed

8 files changed

+480
-471
lines changed

src/interfaces/jdbc/org/postgresql/Connection.java

Lines changed: 305 additions & 305 deletions
Large diffs are not rendered by default.

src/interfaces/jdbc/org/postgresql/ResultSet.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public abstract class ResultSet
1818
protected Vector rows; // The results
1919
protected Field fields[]; // The field descriptions
2020
protected String status; // Status of the result
21+
protected boolean binaryCursor = false; // is the data binary or Strings
2122
protected int updateCount; // How many rows did we get back?
2223
protected int insertOID; // The oid of an inserted row
2324
protected int current_row; // Our pointer to where we are at
@@ -41,7 +42,7 @@ public abstract class ResultSet
4142
* @param updateCount the number of rows affected by the operation
4243
* @param cursor the positioned update/delete cursor name
4344
*/
44-
public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount,int insertOID)
45+
public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount,int insertOID, boolean binaryCursor)
4546
{
4647
this.connection = conn;
4748
this.fields = fields;
@@ -51,6 +52,7 @@ public ResultSet(Connection conn, Field[] fields, Vector tuples, String status,
5152
this.insertOID = insertOID;
5253
this.this_row = null;
5354
this.current_row = -1;
55+
this.binaryCursor = binaryCursor;
5456
}
5557

5658

@@ -65,10 +67,10 @@ public ResultSet(Connection conn, Field[] fields, Vector tuples, String status,
6567
* @param updateCount the number of rows affected by the operation
6668
* @param cursor the positioned update/delete cursor name
6769
*/
68-
public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount)
69-
{
70-
this(conn,fields,tuples,status,updateCount,0);
71-
}
70+
public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount)
71+
{
72+
this(conn,fields,tuples,status,updateCount,0,false);
73+
}
7274

7375
/**
7476
* We at times need to know if the resultSet we are working
@@ -172,7 +174,7 @@ public int getColumnOID(int field)
172174
*/
173175
public int getInsertedOID()
174176
{
175-
return insertOID;
177+
return insertOID;
176178
}
177179

178180
/**

src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java

Lines changed: 119 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* <p>The lifetime of a QueryExecutor object is from sending the query
1414
* until the response has been received from the backend.
1515
*
16-
* $Id: QueryExecutor.java,v 1.1 2001/09/06 03:58:59 momjian Exp $
16+
* $Id: QueryExecutor.java,v 1.2 2001/10/09 20:47:35 barry Exp $
1717
*/
1818

1919
public class QueryExecutor {
@@ -24,24 +24,25 @@ public class QueryExecutor {
2424
private final org.postgresql.Connection connection;
2525

2626
public QueryExecutor(String sql,
27-
java.sql.Statement statement,
28-
PG_Stream pg_stream,
29-
org.postgresql.Connection connection)
30-
throws SQLException
27+
java.sql.Statement statement,
28+
PG_Stream pg_stream,
29+
org.postgresql.Connection connection)
30+
throws SQLException
3131
{
32-
this.sql = sql;
33-
this.statement = statement;
34-
this.pg_stream = pg_stream;
35-
this.connection = connection;
36-
37-
if (statement != null)
38-
maxRows = statement.getMaxRows();
39-
else
40-
maxRows = 0;
32+
this.sql = sql;
33+
this.statement = statement;
34+
this.pg_stream = pg_stream;
35+
this.connection = connection;
36+
37+
if (statement != null)
38+
maxRows = statement.getMaxRows();
39+
else
40+
maxRows = 0;
4141
}
4242

4343
private Field[] fields = null;
4444
private Vector tuples = new Vector();
45+
private boolean binaryCursor = false;
4546
private String status = null;
4647
private int update_count = 1;
4748
private int insert_oid = 0;
@@ -52,84 +53,83 @@ public QueryExecutor(String sql,
5253
*/
5354
public java.sql.ResultSet execute() throws SQLException {
5455

55-
int fqp = 0;
56-
boolean hfr = false;
57-
58-
synchronized(pg_stream) {
59-
60-
sendQuery(sql);
61-
62-
while (!hfr || fqp > 0) {
63-
int c = pg_stream.ReceiveChar();
64-
65-
switch (c)
66-
{
67-
case 'A': // Asynchronous Notify
68-
int pid = pg_stream.ReceiveInteger(4);
69-
String msg = pg_stream.ReceiveString(connection.getEncoding());
70-
break;
71-
case 'B': // Binary Data Transfer
72-
receiveTuple(true);
73-
break;
74-
case 'C': // Command Status
75-
receiveCommandStatus();
76-
77-
if (fields != null)
78-
hfr = true;
79-
else {
80-
sendQuery(" ");
81-
fqp++;
82-
}
83-
break;
84-
case 'D': // Text Data Transfer
85-
receiveTuple(false);
86-
break;
87-
case 'E': // Error Message
88-
throw new SQLException(pg_stream.ReceiveString(connection.getEncoding()));
89-
case 'I': // Empty Query
90-
int t = pg_stream.ReceiveChar();
91-
if (t != 0)
92-
throw new PSQLException("postgresql.con.garbled");
93-
94-
if (fqp > 0)
95-
fqp--;
96-
if (fqp == 0)
97-
hfr = true;
98-
break;
99-
case 'N': // Error Notification
100-
connection.addWarning(pg_stream.ReceiveString(connection.getEncoding()));
101-
break;
102-
case 'P': // Portal Name
103-
String pname = pg_stream.ReceiveString(connection.getEncoding());
104-
break;
105-
case 'T': // MetaData Field Description
106-
receiveFields();
107-
break;
108-
case 'Z': // backend ready for query, ignore for now :-)
109-
break;
110-
default:
111-
throw new PSQLException("postgresql.con.type",
112-
new Character((char) c));
113-
}
114-
}
115-
116-
return connection.getResultSet(connection, statement, fields, tuples, status, update_count, insert_oid);
117-
}
56+
int fqp = 0;
57+
boolean hfr = false;
58+
59+
synchronized(pg_stream) {
60+
61+
sendQuery(sql);
62+
63+
while (!hfr || fqp > 0) {
64+
int c = pg_stream.ReceiveChar();
65+
66+
switch (c)
67+
{
68+
case 'A': // Asynchronous Notify
69+
int pid = pg_stream.ReceiveInteger(4);
70+
String msg = pg_stream.ReceiveString(connection.getEncoding());
71+
break;
72+
case 'B': // Binary Data Transfer
73+
receiveTuple(true);
74+
break;
75+
case 'C': // Command Status
76+
receiveCommandStatus();
77+
78+
if (fields != null)
79+
hfr = true;
80+
else {
81+
sendQuery(" ");
82+
fqp++;
83+
}
84+
break;
85+
case 'D': // Text Data Transfer
86+
receiveTuple(false);
87+
break;
88+
case 'E': // Error Message
89+
throw new SQLException(pg_stream.ReceiveString(connection.getEncoding()));
90+
case 'I': // Empty Query
91+
int t = pg_stream.ReceiveChar();
92+
if (t != 0)
93+
throw new PSQLException("postgresql.con.garbled");
94+
95+
if (fqp > 0)
96+
fqp--;
97+
if (fqp == 0)
98+
hfr = true;
99+
break;
100+
case 'N': // Error Notification
101+
connection.addWarning(pg_stream.ReceiveString(connection.getEncoding()));
102+
break;
103+
case 'P': // Portal Name
104+
String pname = pg_stream.ReceiveString(connection.getEncoding());
105+
break;
106+
case 'T': // MetaData Field Description
107+
receiveFields();
108+
break;
109+
case 'Z': // backend ready for query, ignore for now :-)
110+
break;
111+
default:
112+
throw new PSQLException("postgresql.con.type",
113+
new Character((char) c));
114+
}
115+
}
116+
return connection.getResultSet(connection, statement, fields, tuples, status, update_count, insert_oid, binaryCursor);
117+
}
118118
}
119119

120120
/**
121121
* Send a query to the backend.
122122
*/
123123
private void sendQuery(String query) throws SQLException {
124-
try {
125-
pg_stream.SendChar('Q');
126-
pg_stream.Send(connection.getEncoding().encode(query));
127-
pg_stream.SendChar(0);
128-
pg_stream.flush();
129-
130-
} catch (IOException e) {
131-
throw new PSQLException("postgresql.con.ioerror", e);
132-
}
124+
try {
125+
pg_stream.SendChar('Q');
126+
pg_stream.Send(connection.getEncoding().encode(query));
127+
pg_stream.SendChar(0);
128+
pg_stream.flush();
129+
130+
} catch (IOException e) {
131+
throw new PSQLException("postgresql.con.ioerror", e);
132+
}
133133
}
134134

135135
/**
@@ -138,50 +138,51 @@ private void sendQuery(String query) throws SQLException {
138138
* @param isBinary set if the tuple should be treated as binary data
139139
*/
140140
private void receiveTuple(boolean isBinary) throws SQLException {
141-
if (fields == null)
142-
throw new PSQLException("postgresql.con.tuple");
143-
Object tuple = pg_stream.ReceiveTuple(fields.length, isBinary);
144-
if (maxRows == 0 || tuples.size() < maxRows)
145-
tuples.addElement(tuple);
141+
if (fields == null)
142+
throw new PSQLException("postgresql.con.tuple");
143+
Object tuple = pg_stream.ReceiveTuple(fields.length, isBinary);
144+
if (isBinary) binaryCursor = true;
145+
if (maxRows == 0 || tuples.size() < maxRows)
146+
tuples.addElement(tuple);
146147
}
147148

148149
/**
149150
* Receive command status from the backend.
150151
*/
151152
private void receiveCommandStatus() throws SQLException {
152153

153-
status = pg_stream.ReceiveString(connection.getEncoding());
154-
155-
try {
156-
// Now handle the update count correctly.
157-
if (status.startsWith("INSERT") || status.startsWith("UPDATE") || status.startsWith("DELETE") || status.startsWith("MOVE")) {
158-
update_count = Integer.parseInt(status.substring(1 + status.lastIndexOf(' ')));
159-
}
160-
if (status.startsWith("INSERT")) {
161-
insert_oid = Integer.parseInt(status.substring(1 + status.indexOf(' '),
162-
status.lastIndexOf(' ')));
163-
}
164-
} catch (NumberFormatException nfe) {
165-
throw new PSQLException("postgresql.con.fathom", status);
166-
}
154+
status = pg_stream.ReceiveString(connection.getEncoding());
155+
156+
try {
157+
// Now handle the update count correctly.
158+
if (status.startsWith("INSERT") || status.startsWith("UPDATE") || status.startsWith("DELETE") || status.startsWith("MOVE")) {
159+
update_count = Integer.parseInt(status.substring(1 + status.lastIndexOf(' ')));
160+
}
161+
if (status.startsWith("INSERT")) {
162+
insert_oid = Integer.parseInt(status.substring(1 + status.indexOf(' '),
163+
status.lastIndexOf(' ')));
164+
}
165+
} catch (NumberFormatException nfe) {
166+
throw new PSQLException("postgresql.con.fathom", status);
167+
}
167168
}
168169

169170
/**
170171
* Receive the field descriptions from the back end.
171172
*/
172173
private void receiveFields() throws SQLException {
173-
if (fields != null)
174-
throw new PSQLException("postgresql.con.multres");
175-
176-
int size = pg_stream.ReceiveIntegerR(2);
177-
fields = new Field[size];
178-
179-
for (int i = 0; i < fields.length; i++) {
180-
String typeName = pg_stream.ReceiveString(connection.getEncoding());
181-
int typeOid = pg_stream.ReceiveIntegerR(4);
182-
int typeLength = pg_stream.ReceiveIntegerR(2);
183-
int typeModifier = pg_stream.ReceiveIntegerR(4);
184-
fields[i] = new Field(connection, typeName, typeOid, typeLength, typeModifier);
185-
}
174+
if (fields != null)
175+
throw new PSQLException("postgresql.con.multres");
176+
177+
int size = pg_stream.ReceiveIntegerR(2);
178+
fields = new Field[size];
179+
180+
for (int i = 0; i < fields.length; i++) {
181+
String typeName = pg_stream.ReceiveString(connection.getEncoding());
182+
int typeOid = pg_stream.ReceiveIntegerR(4);
183+
int typeLength = pg_stream.ReceiveIntegerR(2);
184+
int typeModifier = pg_stream.ReceiveIntegerR(4);
185+
fields[i] = new Field(connection, typeName, typeOid, typeLength, typeModifier);
186+
}
186187
}
187188
}

src/interfaces/jdbc/org/postgresql/jdbc1/Connection.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import org.postgresql.util.*;
1818

1919
/**
20-
* $Id: Connection.java,v 1.10 2001/09/10 15:07:05 momjian Exp $
20+
* $Id: Connection.java,v 1.11 2001/10/09 20:47:35 barry Exp $
2121
*
2222
* A Connection represents a session with a specific database. Within the
2323
* context of a Connection, SQL statements are executed and results are
@@ -131,10 +131,10 @@ public java.sql.DatabaseMetaData getMetaData() throws SQLException
131131
* This overides the method in org.postgresql.Connection and returns a
132132
* ResultSet.
133133
*/
134-
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
134+
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
135135
{
136136
// in jdbc1 stat is ignored.
137-
return new org.postgresql.jdbc1.ResultSet((org.postgresql.jdbc1.Connection)conn,fields,tuples,status,updateCount,insertOID);
137+
return new org.postgresql.jdbc1.ResultSet((org.postgresql.jdbc1.Connection)conn,fields,tuples,status,updateCount,insertOID,binaryCursor);
138138
}
139139

140140

src/interfaces/jdbc/org/postgresql/jdbc1/ResultSet.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
7070
* @param updateCount the number of rows affected by the operation
7171
* @param cursor the positioned update/delete cursor name
7272
*/
73-
public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount,int insertOID)
73+
public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount, int insertOID, boolean binaryCursor)
7474
{
75-
super(conn,fields,tuples,status,updateCount,insertOID);
75+
super(conn,fields,tuples,status,updateCount,insertOID,binaryCursor);
7676
}
7777

7878
/**
@@ -86,10 +86,10 @@ public ResultSet(Connection conn, Field[] fields, Vector tuples, String status,
8686
* @param updateCount the number of rows affected by the operation
8787
* @param cursor the positioned update/delete cursor name
8888
*/
89-
public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount)
90-
{
91-
super(conn,fields,tuples,status,updateCount,0);
92-
}
89+
public ResultSet(Connection conn, Field[] fields, Vector tuples, String status, int updateCount)
90+
{
91+
super(conn,fields,tuples,status,updateCount,0,false);
92+
}
9393

9494
/**
9595
* A ResultSet is initially positioned before its first row,
@@ -375,6 +375,9 @@ public byte[] getBytes(int columnIndex) throws SQLException
375375
if (columnIndex < 1 || columnIndex > fields.length)
376376
throw new PSQLException("postgresql.res.colrange");
377377

378+
//If the data is already binary then just return it
379+
if (binaryCursor) return this_row[columnIndex - 1];
380+
378381
if (connection.haveMinimumCompatibleVersion("7.2")) {
379382
//Version 7.2 supports the bytea datatype for byte arrays
380383
return PGbytea.toBytes(getString(columnIndex));

0 commit comments

Comments
 (0)