1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-30 21:42:05 +03:00

Attached is a patch to add bytea support to JDBC.

This patch does the following:

- Adds binary datatype support (bytea)
- Changes getXXXStream()/setXXXStream() methods to be spec compliant
- Adds ability to revert to old behavior

Details:

Adds support for the binary type bytea.  The ResultSet.getBytes() and
PreparedStatement.setBytes() methods now work against columns of bytea
type.  This is a change in behavior from the previous code which assumed
the column type was OID and thus a LargeObject.  The new behavior is
more complient with the JDBC spec as BLOB/CLOB are to be used for
LargeObjects and the getBytes()/setBytes() methods are for the databases
binary datatype (which is bytea in postgres).

Changes the behavior of the getBinaryStream(), getAsciiStream(),
getCharacterStream(), getUnicodeStream() and their setXXXStream()
counterparts.  These methos now work against either the bytea type
(BinaryStream) or the text types (AsciiStream, CharacterStream,
UnicodeStream).  The previous behavior was that these all assumed the
underlying column was of type OID and thus a LargeObject.  The
spec/javadoc for these methods indicate that they are for LONGVARCHAR
and LONGVARBINARY datatypes, which are distinct from the BLOB/CLOB
datatypes.  Given that the bytea and text types support upto 1G, they
are the LONGVARBINARY and LONGVARCHAR datatypes in postgres.

Added support for turning off the above new functionality.  Given that
the changes above are not backwardly compatible (however they are more
spec complient), I added the ability to revert back to the old behavior.
  The Connection now takes an optional parameter named 'compatible'.  If
the value of '7.1' is passed, the driver reverts to the 7.1 behavior.
If the parameter is not passed or the value '7.2' is passed the behavior
is the new behavior.  The mechanism put in place can be used in the
future when/if similar needs arise to change behavior.  This is
patterned after how Oracle does this (i.e. Oracle has a 'compatible'
parameter that behaves in a similar manner).

Misc fixes.  Cleaned up a few things I encountered along the way.


Note that in testing the patch I needed to ignore whitespace differences
in order to get it to apply cleanly (i.e. patch -l -i byteapatch.diff).
Also this patch introduces a new file
(src/interfaces/jdbc/org/postgresql/util/PGbytea.java).

Barry Lind
This commit is contained in:
Bruce Momjian
2001-09-10 15:07:05 +00:00
parent 6b50f9af33
commit ec0ad67403
10 changed files with 557 additions and 49 deletions

View File

@ -374,10 +374,15 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
{
if (columnIndex < 1 || columnIndex > fields.length)
throw new PSQLException("postgresql.res.colrange");
wasNullFlag = (this_row[columnIndex - 1] == null);
if (connection.haveMinimumCompatibleVersion("7.2")) {
//Version 7.2 supports the bytea datatype for byte arrays
return PGbytea.toBytes(getString(columnIndex));
} else {
//Version 7.1 and earlier supports LargeObjects for byte arrays
wasNullFlag = (this_row[columnIndex - 1] == null);
// Handle OID's as BLOBS
if(!wasNullFlag)
if(!wasNullFlag) {
if( fields[columnIndex - 1].getOID() == 26) {
LargeObjectManager lom = connection.getLargeObjectAPI();
LargeObject lob = lom.open(getInt(columnIndex));
@ -385,8 +390,9 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
lob.close();
return buf;
}
return this_row[columnIndex - 1];
}
}
return null;
}
/**
@ -545,8 +551,27 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
*/
public InputStream getAsciiStream(int columnIndex) throws SQLException
{
wasNullFlag = (this_row[columnIndex - 1] == null);
if (wasNullFlag)
return null;
if (connection.haveMinimumCompatibleVersion("7.2")) {
//Version 7.2 supports AsciiStream for all the PG text types
//As the spec/javadoc for this method indicate this is to be used for
//large text values (i.e. LONGVARCHAR) PG doesn't have a separate
//long string datatype, but with toast the text datatype is capable of
//handling very large values. Thus the implementation ends up calling
//getString() since there is no current way to stream the value from the server
try {
return new ByteArrayInputStream(getString(columnIndex).getBytes("ASCII"));
} catch (UnsupportedEncodingException l_uee) {
throw new PSQLException("postgresql.unusual", l_uee);
}
} else {
// In 7.1 Handle as BLOBS so return the LargeObject input stream
return getBinaryStream(columnIndex);
}
}
/**
* A column value can also be retrieved as a stream of Unicode
@ -562,8 +587,27 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
*/
public InputStream getUnicodeStream(int columnIndex) throws SQLException
{
wasNullFlag = (this_row[columnIndex - 1] == null);
if (wasNullFlag)
return null;
if (connection.haveMinimumCompatibleVersion("7.2")) {
//Version 7.2 supports AsciiStream for all the PG text types
//As the spec/javadoc for this method indicate this is to be used for
//large text values (i.e. LONGVARCHAR) PG doesn't have a separate
//long string datatype, but with toast the text datatype is capable of
//handling very large values. Thus the implementation ends up calling
//getString() since there is no current way to stream the value from the server
try {
return new ByteArrayInputStream(getString(columnIndex).getBytes("UTF-8"));
} catch (UnsupportedEncodingException l_uee) {
throw new PSQLException("postgresql.unusual", l_uee);
}
} else {
// In 7.1 Handle as BLOBS so return the LargeObject input stream
return getBinaryStream(columnIndex);
}
}
/**
* A column value can also be retrieved as a binary strea. This
@ -579,11 +623,29 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
*/
public InputStream getBinaryStream(int columnIndex) throws SQLException
{
byte b[] = getBytes(columnIndex);
wasNullFlag = (this_row[columnIndex - 1] == null);
if (wasNullFlag)
return null;
if (connection.haveMinimumCompatibleVersion("7.2")) {
//Version 7.2 supports BinaryStream for all PG bytea type
//As the spec/javadoc for this method indicate this is to be used for
//large binary values (i.e. LONGVARBINARY) PG doesn't have a separate
//long binary datatype, but with toast the bytea datatype is capable of
//handling very large values. Thus the implementation ends up calling
//getBytes() since there is no current way to stream the value from the server
byte b[] = getBytes(columnIndex);
if (b != null)
return new ByteArrayInputStream(b);
return null; // SQL NULL
} else {
// In 7.1 Handle as BLOBS so return the LargeObject input stream
if( fields[columnIndex - 1].getOID() == 26) {
LargeObjectManager lom = connection.getLargeObjectAPI();
LargeObject lob = lom.open(getInt(columnIndex));
return lob.getInputStream();
}
}
return null;
}
/**