diff options
author | Barry Lind <barry@xythos.com> | 2003-08-24 22:10:09 +0000 |
---|---|---|
committer | Barry Lind <barry@xythos.com> | 2003-08-24 22:10:09 +0000 |
commit | 2495365df10c2d6c2bf29988af7d875bb81a69b7 (patch) | |
tree | b4fb09d1810779564d89b8d66918a9c85e6592be /src | |
parent | 478bb0268fa5b193a3269a4690b78bbf25cd0990 (diff) | |
download | postgresql-2495365df10c2d6c2bf29988af7d875bb81a69b7.tar.gz postgresql-2495365df10c2d6c2bf29988af7d875bb81a69b7.zip |
Applied patches from Oliver Jowett to fix the following bugs:
- adds a finalizer method to AbstractJdbc1Statement to clean up in the case of
poor user code which fails to close the statement object
- fix ant build file to correctly detect dependencies across jdbc1/jdbc2/jdbc3
- fix a coupld of server prepared statement bugs and added regression test for
them
Applied patch from Kim Ho:
- adds support for get/setMaxFieldSize().
Also fixed build.xml to provide a better error message in the event that an
older version of the driver exists in the classpath when trying to build.
Diffstat (limited to 'src')
10 files changed, 134 insertions, 32 deletions
diff --git a/src/interfaces/jdbc/build.xml b/src/interfaces/jdbc/build.xml index fed207ed828..633daa72db3 100644 --- a/src/interfaces/jdbc/build.xml +++ b/src/interfaces/jdbc/build.xml @@ -6,7 +6,7 @@ This file now requires Ant 1.4.1. 2002-04-18 - $Header: /cvsroot/pgsql/src/interfaces/jdbc/Attic/build.xml,v 1.35 2003/08/11 23:42:04 barry Exp $ + $Header: /cvsroot/pgsql/src/interfaces/jdbc/Attic/build.xml,v 1.36 2003/08/24 22:10:09 barry Exp $ --> @@ -108,19 +108,45 @@ </target> - <!-- This is the core of the driver. It is common for all three versions. --> <target name="compile" depends="prepare,check_versions,driver"> - <javac srcdir="${srcdir}" destdir="${builddir}" debug="${debug}"> - <include name="${package}/**" /> - - <exclude name="${package}/jdbc1/**" unless="jdbc1"/> - <exclude name="${package}/jdbc2/**" unless="jdbc2"/> - <exclude name="${package}/jdbc3/**" unless="jdbc3"/> - <exclude name="${package}/jdbc2/optional/**" unless="jdbc2" /> - <exclude name="${package}/jdbc2/optional/**" unless="datasource" /> + <available classname="org.postgresql.Driver" property="old.driver.present" /> + <fail message="Old driver was detected on classpath or in jre/lib/ext, please remove and try again." if="old.driver.present" /> + + <javac classpath="{$srcdir}" srcdir="${srcdir}" destdir="${builddir}" debug="${debug}"> + <!-- This is the core of the driver. It is common for all three versions. --> + <include name="${package}/*.java" /> + <include name="${package}/core/**" /> + <include name="${package}/fastpath/**" /> + <include name="${package}/geometric/**" /> + <include name="${package}/largeobject/**" /> + <include name="${package}/util/**" /> + + <!-- + Each jdbcN subpackage is used only if the driver supports *at least* that + revision of JDBC. That is, a JDBC1 build uses only jdbc1, a JDBC2 build + uses both jdbc1 and jdbc2, etc. + + Within those subpackages, classes beginning with "JdbcN" are assumed to be + the concrete implementations for JDBC version N and are built only if the + driver supports *exactly* that version. For example, jdbc1/Jdbc1Statement.java + is built only if the driver build is a JDBC1 build. + --> + + <!-- jdbc1 subpackage --> + <include name="${package}/jdbc1/**"/> + <exclude name="${package}/jdbc1/Jdbc1*.java" unless="jdbc1"/> + + <!-- jdbc2 subpackage --> + <include name="${package}/jdbc2/**" if="jdbc2"/> + <include name="${package}/jdbc2/**" if="jdbc3"/> + <exclude name="${package}/jdbc2/Jdbc2*.java" unless="jdbc2"/> + <exclude name="${package}/jdbc2/optional/**" unless="datasource"/> + + <!-- jdbc3 subpackage --> + <include name="${package}/jdbc3/*.java" if="jdbc3"/> + <exclude name="${package}/jdbc3/Jdbc3*.java" unless="jdbc3"/> - <exclude name="${package}/test/**"/> </javac> </target> diff --git a/src/interfaces/jdbc/org/postgresql/core/BaseStatement.java b/src/interfaces/jdbc/org/postgresql/core/BaseStatement.java index 5811eb1dab8..c91e259e1d7 100644 --- a/src/interfaces/jdbc/org/postgresql/core/BaseStatement.java +++ b/src/interfaces/jdbc/org/postgresql/core/BaseStatement.java @@ -6,7 +6,7 @@ * Copyright (c) 2003, PostgreSQL Global Development Group * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/core/Attic/BaseStatement.java,v 1.4 2003/08/11 20:54:55 barry Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/core/Attic/BaseStatement.java,v 1.5 2003/08/24 22:10:09 barry Exp $ * *------------------------------------------------------------------------- */ @@ -31,9 +31,11 @@ public interface BaseStatement extends org.postgresql.PGStatement public void addWarning(String p_warning) throws SQLException; public void close() throws SQLException; public int getFetchSize() throws SQLException; + public int getMaxFieldSize() throws SQLException; public int getMaxRows() throws SQLException; public int getResultSetConcurrency() throws SQLException; public String getStatementName(); public SQLWarning getWarnings() throws SQLException; + public void setMaxFieldSize(int max) throws SQLException; } diff --git a/src/interfaces/jdbc/org/postgresql/errors.properties b/src/interfaces/jdbc/org/postgresql/errors.properties index 21b1a2941ca..6f5f2550ab3 100644 --- a/src/interfaces/jdbc/org/postgresql/errors.properties +++ b/src/interfaces/jdbc/org/postgresql/errors.properties @@ -71,7 +71,6 @@ postgresql.serial.noclass:No class found for {0} postgresql.serial.table:The table for {0} is not in the database. Contact the DBA, as the database is in an inconsistent state. postgresql.serial.underscore:Class names may not have _ in them. You supplied {0}. postgresql.stat.batch.error:Batch entry {0} {1} was aborted. Call getNextException() to see the cause. -postgresql.stat.maxfieldsize:An attempt to setMaxFieldSize() failed - compile time default in force. postgresql.stat.noresult:No results were returned by the query. postgresql.stat.result:A result was returned when none was expected. postgresql.stream.eof:The backend has broken the connection. Possibly the action you have attempted has caused it to close. @@ -103,3 +102,4 @@ postgresql.input.rows.gt0:Maximum number of rows must be a value greater than or postgresql.format.baddate:The date given: {0} does not match the format required: {1}. postgresql.format.badtime:The time given: {0} does not match the format required: {1}. postgresql.format.badtimestamp:The timestamp given {0} does not match the format required: {1}. +postgresql.input.field.gt0:The maximum field size must be a value greater than or equal to 0. diff --git a/src/interfaces/jdbc/org/postgresql/errors_de.properties b/src/interfaces/jdbc/org/postgresql/errors_de.properties index ed641e985a7..11fd7bbcee8 100644 --- a/src/interfaces/jdbc/org/postgresql/errors_de.properties +++ b/src/interfaces/jdbc/org/postgresql/errors_de.properties @@ -1,7 +1,7 @@ # Message translation file for PostgreSQL JDBC driver # Peter Eisentraut <peter_e@gmx.net>, 2001. # -# $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Attic/errors_de.properties,v 1.4 2003/02/12 06:13:04 barry Exp $ +# $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Attic/errors_de.properties,v 1.5 2003/08/24 22:10:09 barry Exp $ postgresql.con.auth:Der Authentifizierungstyp »{0}« wird nicht unterstützt. postgresql.con.authfail:Ein Fehler trat auf während die Authentifizierungsanfrage empfangen wurde. @@ -66,7 +66,6 @@ postgresql.serial.noclass:Keine Klasse für Typ »{0}« gefunden postgresql.serial.table:Keine Tabelle für Typ »{0}« in der Datenbank gefunden. Die Datenbank ist in einem unbeständigen Zustand. postgresql.serial.underscore:Zu serialisierende Klassennamen dürfen keine Unterstriche (_) enthälten. Der angegebene Name war »{0}«. postgresql.stat.batch.error:Batch-Anweisung Nummer {0} ({1}) wurde abgebrochen. -postgresql.stat.maxfieldsize:setMaxFieldSize() is nicht möglich; die Grenze ist fest eingebaut. postgresql.stat.noresult:Die Abfrage ergab kein Ergebnis. postgresql.stat.result:Die Anweisung ergab einen Abfrageergebnissatz, obwohl keiner erwartet wurde. postgresql.stream.encoding:Nicht unterstützte Kodierung: {0} diff --git a/src/interfaces/jdbc/org/postgresql/errors_it.properties b/src/interfaces/jdbc/org/postgresql/errors_it.properties index 76e6168110e..197eac24d69 100644 --- a/src/interfaces/jdbc/org/postgresql/errors_it.properties +++ b/src/interfaces/jdbc/org/postgresql/errors_it.properties @@ -65,7 +65,6 @@ postgresql.serial.noclass:Nessuna classe trovata per {0}. postgresql.serial.table:La tabella per {0} non è nel database. Contattare l'amministratore del DB, visto che il database è in uno stato incosistente. postgresql.serial.underscore:Il nome di una classe non può contenere il carattere ``_''. E` stato fornito {0}. postgresql.stat.batch.error:L'operazione {0} {1} della sequenza è stata annullata. -postgresql.stat.maxfieldsize:Fallito un tentativo a setMaxFieldSize() - verrà utilizzato il valore predefinito a tempo di compilazione. postgresql.stat.noresult:Nessun risultato è stato restituito dalla query. postgresql.stream.eof:Il backend ha interrotto la connessione. Probabilmente la tua azione ha causato la sua uscita. postgresql.stream.flush:Si è verificato un errore di I/O mentre si svuotava il buffer d'uscita - {0} diff --git a/src/interfaces/jdbc/org/postgresql/errors_nl.properties b/src/interfaces/jdbc/org/postgresql/errors_nl.properties index 2e5388a2278..1dc93453bcc 100644 --- a/src/interfaces/jdbc/org/postgresql/errors_nl.properties +++ b/src/interfaces/jdbc/org/postgresql/errors_nl.properties @@ -55,7 +55,6 @@ postgresql.serial.noclass:Geen class gevonden voor {0}. postgresql.serial.table:De tabel voor {0} is niet in de database. Neem contact op met de DBA, omdat de database in een inconsistente staat verkeert. postgresql.serial.underscore:Class namen mogen geen _ in zich hebben. Jij voerde {0} in. postgresql.stat.batch.error:Batch invoer {0} {1} werd afgebroken. -postgresql.stat.maxfieldsize:Een poging om setMaxFieldSize() faalde - compiletime standaardwaarde van kracht. postgresql.stat.noresult:Geen resultaten werden teruggegeven door de query. postgresql.stream.eof:De achterkant heeft de verbinding verbroken. Mogelijk was de actie die je probeerde de oorzaak hiervan. postgresql.stream.flush:Een I/O fout trad op tijdens het legen van de uitvoer - {0} diff --git a/src/interfaces/jdbc/org/postgresql/errors_zh_TW.properties b/src/interfaces/jdbc/org/postgresql/errors_zh_TW.properties index 799893b1007..62279f395e4 100644 --- a/src/interfaces/jdbc/org/postgresql/errors_zh_TW.properties +++ b/src/interfaces/jdbc/org/postgresql/errors_zh_TW.properties @@ -70,7 +70,6 @@ postgresql.serial.noclass:\u627e\u4e0d\u5230\u985e\u5225{0}\u3002 postgresql.serial.table:\u8655\u7406{0}\u6642\u627e\u4e0d\u5230\u8cc7\u6599\u8868\uff0c\u8cc7\u6599\u5eab\u72c0\u614b\u4e0d\u6b63\u5e38\uff0c\u8acb\u806f\u7d61DBA\u8655\u7406\u3002 postgresql.serial.underscore:\u985e\u5225\u540d\u7a31\u4e0d\u80fd\u4f7f\u7528_\u5b57\u5143\uff0c\u60a8\u6240\u7528\u7684\u540d\u7a31\u662f{0}\u3002 postgresql.stat.batch.error:\u6279\u6b21\u8655\u7406\u5ffd\u7565{0} {1}\u3002 -postgresql.stat.maxfieldsize:setMaxFieldSize()\u5931\u6557 - \u4f7f\u7528\u9810\u8a2d\u503c postgresql.stat.noresult:\u6c92\u6709\u50b3\u56de\u4efb\u4f55\u67e5\u8a62\u7d50\u679c\u3002 postgresql.stat.result:\u50b3\u56de\u9810\u671f\u5916\u7684\u7d50\u679c\u3002 postgresql.stream.eof:\u5f8c\u7aef\u7d50\u675f\u9023\u7dda\uff0c\u4e5f\u8a31\u662f\u56e0\u70ba\u60a8\u6240\u57f7\u884c\u7684\u52d5\u4f5c\u5c0e\u81f4\u9023\u7dda\u4e2d\u65b7\u3002 diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java index c314b77d65a..5a8994f7a42 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java @@ -9,7 +9,7 @@ * Copyright (c) 2003, PostgreSQL Global Development Group * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1ResultSet.java,v 1.14 2003/08/06 05:53:13 barry Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1ResultSet.java,v 1.15 2003/08/24 22:10:09 barry Exp $ * *------------------------------------------------------------------------- */ @@ -176,7 +176,7 @@ public abstract class AbstractJdbc1ResultSet implements BaseResultSet return null; Encoding encoding = connection.getEncoding(); - return encoding.decode(this_row[columnIndex - 1]); + return trimString(columnIndex, encoding.decode(this_row[columnIndex-1])); } public boolean getBoolean(int columnIndex) throws SQLException @@ -303,11 +303,11 @@ public abstract class AbstractJdbc1ResultSet implements BaseResultSet //Version 7.2 supports the bytea datatype for byte arrays if (fields[columnIndex - 1].getPGType().equals("bytea")) { - return PGbytea.toBytes(this_row[columnIndex - 1]); + return trimBytes(columnIndex, PGbytea.toBytes(this_row[columnIndex - 1])); } else { - return this_row[columnIndex - 1]; + return trimBytes(columnIndex, this_row[columnIndex - 1]); } } else @@ -320,11 +320,11 @@ public abstract class AbstractJdbc1ResultSet implements BaseResultSet LargeObject lob = lom.open(getInt(columnIndex)); byte buf[] = lob.read(lob.size()); lob.close(); - return buf; + return trimBytes(columnIndex, buf); } else { - return this_row[columnIndex - 1]; + return trimBytes(columnIndex, this_row[columnIndex - 1]); } } } @@ -1143,7 +1143,54 @@ public abstract class AbstractJdbc1ResultSet implements BaseResultSet } } } + + private boolean isColumnTrimmable(int columnIndex) throws SQLException + { + switch (fields[columnIndex-1].getSQLType()) + { + case Types.CHAR: + case Types.VARCHAR: + case Types.LONGVARCHAR: + case Types.BINARY: + case Types.VARBINARY: + case Types.LONGVARBINARY: + return true; + } + return false; + } + private byte[] trimBytes(int p_columnIndex, byte[] p_bytes) throws SQLException + { + int l_maxSize = statement.getMaxFieldSize(); + //we need to trim if maxsize is set and the length is greater than maxsize and the + //type of this column is a candidate for trimming + if (l_maxSize > 0 && p_bytes.length > l_maxSize && isColumnTrimmable(p_columnIndex)) + { + byte[] l_bytes = new byte[l_maxSize]; + System.arraycopy (p_bytes, 0, l_bytes, 0, l_maxSize); + return l_bytes; + } + else + { + return p_bytes; + } + } + + private String trimString(int p_columnIndex, String p_string) throws SQLException + { + int l_maxSize = statement.getMaxFieldSize(); + //we need to trim if maxsize is set and the length is greater than maxsize and the + //type of this column is a candidate for trimming + if (l_maxSize > 0 && p_string.length() > l_maxSize && isColumnTrimmable(p_columnIndex)) + { + return p_string.substring(0,l_maxSize); + } + else + { + return p_string; + } + } + public SimpleDateFormat getTimestampTZFormat() { if (m_tstzFormat == null) { m_tstzFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java index e4ab3f7cf2c..60b57083645 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java @@ -25,7 +25,7 @@ import java.sql.Timestamp; import java.sql.Types; import java.util.Vector; -/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.31 2003/08/11 21:12:00 barry Exp $ +/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.32 2003/08/24 22:10:09 barry Exp $ * This class defines methods of the jdbc1 specification. This class is * extended by org.postgresql.jdbc2.AbstractJdbc2Statement which adds the jdbc2 * methods. The real Statement class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Statement @@ -87,7 +87,7 @@ public abstract class AbstractJdbc1Statement implements BaseStatement // returnTypeSet is true when a proper call to registerOutParameter has been made private boolean returnTypeSet; protected Object callResult; - + protected static int maxfieldSize = 0; public abstract BaseResultSet createResultSet(Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException; @@ -640,19 +640,19 @@ public abstract class AbstractJdbc1Statement implements BaseStatement */ public int getMaxFieldSize() throws SQLException { - return 8192; // We cannot change this + return maxfieldSize; } /* - * Sets the maxFieldSize - NOT! - We throw an SQLException just - * to inform them to stop doing this. + * Sets the maxFieldSize * * @param max the new max column size limit; zero means unlimited * @exception SQLException if a database access error occurs */ public void setMaxFieldSize(int max) throws SQLException { - throw new PSQLException("postgresql.stat.maxfieldsize"); + if (max < 0) throw new PSQLException("postgresql.input.field.gt0"); + maxfieldSize = max; } /* @@ -721,6 +721,15 @@ public abstract class AbstractJdbc1Statement implements BaseStatement result = null; } + /** + * This finalizer ensures that statements that have allocated server-side + * resources free them when they become unreferenced. + */ + protected void finalize() { + try { close(); } + catch (SQLException e) {} + } + /* * Filter the SQL string of Java SQL Escape clauses. * @@ -1088,7 +1097,7 @@ public abstract class AbstractJdbc1Statement implements BaseStatement } else { - setString(parameterIndex, PGbytea.toPGString(x), PG_TEXT); + setString(parameterIndex, PGbytea.toPGString(x), PG_BYTEA); } } else @@ -2055,7 +2064,7 @@ public abstract class AbstractJdbc1Statement implements BaseStatement if (connection.haveMinimumServerVersion("7.3")) { //If turning server prepared statements off deallocate statement //and reset statement name - if (m_useServerPrepare != flag && !flag) + if (m_useServerPrepare != flag && !flag && m_statementName != null) connection.execSQL("DEALLOCATE " + m_statementName); m_statementName = null; m_useServerPrepare = flag; diff --git a/src/interfaces/jdbc/org/postgresql/test/jdbc2/ServerPreparedStmtTest.java b/src/interfaces/jdbc/org/postgresql/test/jdbc2/ServerPreparedStmtTest.java index dcd85572b7b..ea819b36333 100644 --- a/src/interfaces/jdbc/org/postgresql/test/jdbc2/ServerPreparedStmtTest.java +++ b/src/interfaces/jdbc/org/postgresql/test/jdbc2/ServerPreparedStmtTest.java @@ -153,4 +153,26 @@ public class ServerPreparedStmtTest extends TestCase pstmt.close(); } + public void testSPSToggle() throws Exception + { + // Verify we can toggle UseServerPrepare safely before a query is executed. + PreparedStatement pstmt = con.prepareStatement("SELECT * FROM testsps WHERE id = 2"); + ((PGStatement)pstmt).setUseServerPrepare(true); + ((PGStatement)pstmt).setUseServerPrepare(false); + } + + public void testBytea() throws Exception + { + // Verify we can use setBytes() with a server-prepared update. + try { + TestUtil.createTable(con, "testsps_bytea", "data bytea"); + + PreparedStatement pstmt = con.prepareStatement("INSERT INTO testsps_bytea(data) VALUES (?)"); + ((PGStatement)pstmt).setUseServerPrepare(true); + pstmt.setBytes(1, new byte[100]); + pstmt.executeUpdate(); + } finally { + TestUtil.dropTable(con, "testsps_bytea"); + } + } } |