Skip to content

Commit 2495365

Browse files
author
Barry Lind
committed
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.
1 parent 478bb02 commit 2495365

File tree

10 files changed

+134
-32
lines changed

10 files changed

+134
-32
lines changed

src/interfaces/jdbc/build.xml

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
77
This file now requires Ant 1.4.1. 2002-04-18
88
9-
$Header: /cvsroot/pgsql/src/interfaces/jdbc/Attic/build.xml,v 1.35 2003/08/11 23:42:04 barry Exp $
9+
$Header: /cvsroot/pgsql/src/interfaces/jdbc/Attic/build.xml,v 1.36 2003/08/24 22:10:09 barry Exp $
1010
1111
-->
1212

@@ -108,19 +108,45 @@
108108
</target>
109109

110110

111-
<!-- This is the core of the driver. It is common for all three versions. -->
112111
<target name="compile" depends="prepare,check_versions,driver">
113-
<javac srcdir="${srcdir}" destdir="${builddir}" debug="${debug}">
114-
<include name="${package}/**" />
115-
116-
<exclude name="${package}/jdbc1/**" unless="jdbc1"/>
117-
<exclude name="${package}/jdbc2/**" unless="jdbc2"/>
118-
<exclude name="${package}/jdbc3/**" unless="jdbc3"/>
119112

120-
<exclude name="${package}/jdbc2/optional/**" unless="jdbc2" />
121-
<exclude name="${package}/jdbc2/optional/**" unless="datasource" />
113+
<available classname="org.postgresql.Driver" property="old.driver.present" />
114+
<fail message="Old driver was detected on classpath or in jre/lib/ext, please remove and try again." if="old.driver.present" />
115+
116+
<javac classpath="{$srcdir}" srcdir="${srcdir}" destdir="${builddir}" debug="${debug}">
117+
<!-- This is the core of the driver. It is common for all three versions. -->
118+
<include name="${package}/*.java" />
119+
<include name="${package}/core/**" />
120+
<include name="${package}/fastpath/**" />
121+
<include name="${package}/geometric/**" />
122+
<include name="${package}/largeobject/**" />
123+
<include name="${package}/util/**" />
124+
125+
<!--
126+
Each jdbcN subpackage is used only if the driver supports *at least* that
127+
revision of JDBC. That is, a JDBC1 build uses only jdbc1, a JDBC2 build
128+
uses both jdbc1 and jdbc2, etc.
129+
130+
Within those subpackages, classes beginning with "JdbcN" are assumed to be
131+
the concrete implementations for JDBC version N and are built only if the
132+
driver supports *exactly* that version. For example, jdbc1/Jdbc1Statement.java
133+
is built only if the driver build is a JDBC1 build.
134+
-->
135+
136+
<!-- jdbc1 subpackage -->
137+
<include name="${package}/jdbc1/**"/>
138+
<exclude name="${package}/jdbc1/Jdbc1*.java" unless="jdbc1"/>
139+
140+
<!-- jdbc2 subpackage -->
141+
<include name="${package}/jdbc2/**" if="jdbc2"/>
142+
<include name="${package}/jdbc2/**" if="jdbc3"/>
143+
<exclude name="${package}/jdbc2/Jdbc2*.java" unless="jdbc2"/>
144+
<exclude name="${package}/jdbc2/optional/**" unless="datasource"/>
145+
146+
<!-- jdbc3 subpackage -->
147+
<include name="${package}/jdbc3/*.java" if="jdbc3"/>
148+
<exclude name="${package}/jdbc3/Jdbc3*.java" unless="jdbc3"/>
122149

123-
<exclude name="${package}/test/**"/>
124150
</javac>
125151
</target>
126152

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Copyright (c) 2003, PostgreSQL Global Development Group
77
*
88
* IDENTIFICATION
9-
* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/core/Attic/BaseStatement.java,v 1.4 2003/08/11 20:54:55 barry Exp $
9+
* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/core/Attic/BaseStatement.java,v 1.5 2003/08/24 22:10:09 barry Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -31,9 +31,11 @@ public interface BaseStatement extends org.postgresql.PGStatement
3131
public void addWarning(String p_warning) throws SQLException;
3232
public void close() throws SQLException;
3333
public int getFetchSize() throws SQLException;
34+
public int getMaxFieldSize() throws SQLException;
3435
public int getMaxRows() throws SQLException;
3536
public int getResultSetConcurrency() throws SQLException;
3637
public String getStatementName();
3738
public SQLWarning getWarnings() throws SQLException;
39+
public void setMaxFieldSize(int max) throws SQLException;
3840

3941
}

src/interfaces/jdbc/org/postgresql/errors.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ postgresql.serial.noclass:No class found for {0}
7171
postgresql.serial.table:The table for {0} is not in the database. Contact the DBA, as the database is in an inconsistent state.
7272
postgresql.serial.underscore:Class names may not have _ in them. You supplied {0}.
7373
postgresql.stat.batch.error:Batch entry {0} {1} was aborted. Call getNextException() to see the cause.
74-
postgresql.stat.maxfieldsize:An attempt to setMaxFieldSize() failed - compile time default in force.
7574
postgresql.stat.noresult:No results were returned by the query.
7675
postgresql.stat.result:A result was returned when none was expected.
7776
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
103102
postgresql.format.baddate:The date given: {0} does not match the format required: {1}.
104103
postgresql.format.badtime:The time given: {0} does not match the format required: {1}.
105104
postgresql.format.badtimestamp:The timestamp given {0} does not match the format required: {1}.
105+
postgresql.input.field.gt0:The maximum field size must be a value greater than or equal to 0.

src/interfaces/jdbc/org/postgresql/errors_de.properties

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Message translation file for PostgreSQL JDBC driver
22
# Peter Eisentraut <peter_e@gmx.net>, 2001.
33
#
4-
# $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Attic/errors_de.properties,v 1.4 2003/02/12 06:13:04 barry Exp $
4+
# $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Attic/errors_de.properties,v 1.5 2003/08/24 22:10:09 barry Exp $
55

66
postgresql.con.auth:Der Authentifizierungstyp »{0}« wird nicht unterstützt.
77
postgresql.con.authfail:Ein Fehler trat auf während die Authentifizierungsanfrage empfangen wurde.
@@ -66,7 +66,6 @@ postgresql.serial.noclass:Keine Klasse f
6666
postgresql.serial.table:Keine Tabelle für Typ »{0}« in der Datenbank gefunden. Die Datenbank ist in einem unbeständigen Zustand.
6767
postgresql.serial.underscore:Zu serialisierende Klassennamen dürfen keine Unterstriche (_) enthälten. Der angegebene Name war »{0}«.
6868
postgresql.stat.batch.error:Batch-Anweisung Nummer {0} ({1}) wurde abgebrochen.
69-
postgresql.stat.maxfieldsize:setMaxFieldSize() is nicht möglich; die Grenze ist fest eingebaut.
7069
postgresql.stat.noresult:Die Abfrage ergab kein Ergebnis.
7170
postgresql.stat.result:Die Anweisung ergab einen Abfrageergebnissatz, obwohl keiner erwartet wurde.
7271
postgresql.stream.encoding:Nicht unterstützte Kodierung: {0}

src/interfaces/jdbc/org/postgresql/errors_it.properties

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ postgresql.serial.noclass:Nessuna classe trovata per {0}.
6565
postgresql.serial.table:La tabella per {0} non è nel database. Contattare l'amministratore del DB, visto che il database è in uno stato incosistente.
6666
postgresql.serial.underscore:Il nome di una classe non può contenere il carattere ``_''. E` stato fornito {0}.
6767
postgresql.stat.batch.error:L'operazione {0} {1} della sequenza è stata annullata.
68-
postgresql.stat.maxfieldsize:Fallito un tentativo a setMaxFieldSize() - verrà utilizzato il valore predefinito a tempo di compilazione.
6968
postgresql.stat.noresult:Nessun risultato è stato restituito dalla query.
7069
postgresql.stream.eof:Il backend ha interrotto la connessione. Probabilmente la tua azione ha causato la sua uscita.
7170
postgresql.stream.flush:Si è verificato un errore di I/O mentre si svuotava il buffer d'uscita - {0}

src/interfaces/jdbc/org/postgresql/errors_nl.properties

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ postgresql.serial.noclass:Geen class gevonden voor {0}.
5555
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.
5656
postgresql.serial.underscore:Class namen mogen geen _ in zich hebben. Jij voerde {0} in.
5757
postgresql.stat.batch.error:Batch invoer {0} {1} werd afgebroken.
58-
postgresql.stat.maxfieldsize:Een poging om setMaxFieldSize() faalde - compiletime standaardwaarde van kracht.
5958
postgresql.stat.noresult:Geen resultaten werden teruggegeven door de query.
6059
postgresql.stream.eof:De achterkant heeft de verbinding verbroken. Mogelijk was de actie die je probeerde de oorzaak hiervan.
6160
postgresql.stream.flush:Een I/O fout trad op tijdens het legen van de uitvoer - {0}

src/interfaces/jdbc/org/postgresql/errors_zh_TW.properties

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ postgresql.serial.noclass:\u627e\u4e0d\u5230\u985e\u5225{0}\u3002
7070
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
7171
postgresql.serial.underscore:\u985e\u5225\u540d\u7a31\u4e0d\u80fd\u4f7f\u7528_\u5b57\u5143\uff0c\u60a8\u6240\u7528\u7684\u540d\u7a31\u662f{0}\u3002
7272
postgresql.stat.batch.error:\u6279\u6b21\u8655\u7406\u5ffd\u7565{0} {1}\u3002
73-
postgresql.stat.maxfieldsize:setMaxFieldSize()\u5931\u6557 - \u4f7f\u7528\u9810\u8a2d\u503c
7473
postgresql.stat.noresult:\u6c92\u6709\u50b3\u56de\u4efb\u4f55\u67e5\u8a62\u7d50\u679c\u3002
7574
postgresql.stat.result:\u50b3\u56de\u9810\u671f\u5916\u7684\u7d50\u679c\u3002
7675
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

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

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Copyright (c) 2003, PostgreSQL Global Development Group
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1ResultSet.java,v 1.14 2003/08/06 05:53:13 barry Exp $
12+
* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1ResultSet.java,v 1.15 2003/08/24 22:10:09 barry Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -176,7 +176,7 @@ public String getString(int columnIndex) throws SQLException
176176
return null;
177177

178178
Encoding encoding = connection.getEncoding();
179-
return encoding.decode(this_row[columnIndex - 1]);
179+
return trimString(columnIndex, encoding.decode(this_row[columnIndex-1]));
180180
}
181181

182182
public boolean getBoolean(int columnIndex) throws SQLException
@@ -303,11 +303,11 @@ else if (connection.haveMinimumCompatibleVersion("7.2"))
303303
//Version 7.2 supports the bytea datatype for byte arrays
304304
if (fields[columnIndex - 1].getPGType().equals("bytea"))
305305
{
306-
return PGbytea.toBytes(this_row[columnIndex - 1]);
306+
return trimBytes(columnIndex, PGbytea.toBytes(this_row[columnIndex - 1]));
307307
}
308308
else
309309
{
310-
return this_row[columnIndex - 1];
310+
return trimBytes(columnIndex, this_row[columnIndex - 1]);
311311
}
312312
}
313313
else
@@ -320,11 +320,11 @@ else if (connection.haveMinimumCompatibleVersion("7.2"))
320320
LargeObject lob = lom.open(getInt(columnIndex));
321321
byte buf[] = lob.read(lob.size());
322322
lob.close();
323-
return buf;
323+
return trimBytes(columnIndex, buf);
324324
}
325325
else
326326
{
327-
return this_row[columnIndex - 1];
327+
return trimBytes(columnIndex, this_row[columnIndex - 1]);
328328
}
329329
}
330330
}
@@ -1143,7 +1143,54 @@ else if (slen == 19)
11431143
}
11441144
}
11451145
}
1146+
1147+
private boolean isColumnTrimmable(int columnIndex) throws SQLException
1148+
{
1149+
switch (fields[columnIndex-1].getSQLType())
1150+
{
1151+
case Types.CHAR:
1152+
case Types.VARCHAR:
1153+
case Types.LONGVARCHAR:
1154+
case Types.BINARY:
1155+
case Types.VARBINARY:
1156+
case Types.LONGVARBINARY:
1157+
return true;
1158+
}
1159+
return false;
1160+
}
11461161

1162+
private byte[] trimBytes(int p_columnIndex, byte[] p_bytes) throws SQLException
1163+
{
1164+
int l_maxSize = statement.getMaxFieldSize();
1165+
//we need to trim if maxsize is set and the length is greater than maxsize and the
1166+
//type of this column is a candidate for trimming
1167+
if (l_maxSize > 0 && p_bytes.length > l_maxSize && isColumnTrimmable(p_columnIndex))
1168+
{
1169+
byte[] l_bytes = new byte[l_maxSize];
1170+
System.arraycopy (p_bytes, 0, l_bytes, 0, l_maxSize);
1171+
return l_bytes;
1172+
}
1173+
else
1174+
{
1175+
return p_bytes;
1176+
}
1177+
}
1178+
1179+
private String trimString(int p_columnIndex, String p_string) throws SQLException
1180+
{
1181+
int l_maxSize = statement.getMaxFieldSize();
1182+
//we need to trim if maxsize is set and the length is greater than maxsize and the
1183+
//type of this column is a candidate for trimming
1184+
if (l_maxSize > 0 && p_string.length() > l_maxSize && isColumnTrimmable(p_columnIndex))
1185+
{
1186+
return p_string.substring(0,l_maxSize);
1187+
}
1188+
else
1189+
{
1190+
return p_string;
1191+
}
1192+
}
1193+
11471194
public SimpleDateFormat getTimestampTZFormat() {
11481195
if (m_tstzFormat == null) {
11491196
m_tstzFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");

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

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import java.sql.Types;
2626
import java.util.Vector;
2727

28-
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.31 2003/08/11 21:12:00 barry Exp $
28+
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.32 2003/08/24 22:10:09 barry Exp $
2929
* This class defines methods of the jdbc1 specification. This class is
3030
* extended by org.postgresql.jdbc2.AbstractJdbc2Statement which adds the jdbc2
3131
* methods. The real Statement class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Statement
@@ -87,7 +87,7 @@ public abstract class AbstractJdbc1Statement implements BaseStatement
8787
// returnTypeSet is true when a proper call to registerOutParameter has been made
8888
private boolean returnTypeSet;
8989
protected Object callResult;
90-
90+
protected static int maxfieldSize = 0;
9191

9292
public abstract BaseResultSet createResultSet(Field[] fields, Vector tuples, String status, int updateCount, long insertOID, boolean binaryCursor) throws SQLException;
9393

@@ -640,19 +640,19 @@ public SQLWarning getWarnings() throws SQLException
640640
*/
641641
public int getMaxFieldSize() throws SQLException
642642
{
643-
return 8192; // We cannot change this
643+
return maxfieldSize;
644644
}
645645

646646
/*
647-
* Sets the maxFieldSize - NOT! - We throw an SQLException just
648-
* to inform them to stop doing this.
647+
* Sets the maxFieldSize
649648
*
650649
* @param max the new max column size limit; zero means unlimited
651650
* @exception SQLException if a database access error occurs
652651
*/
653652
public void setMaxFieldSize(int max) throws SQLException
654653
{
655-
throw new PSQLException("postgresql.stat.maxfieldsize");
654+
if (max < 0) throw new PSQLException("postgresql.input.field.gt0");
655+
maxfieldSize = max;
656656
}
657657

658658
/*
@@ -721,6 +721,15 @@ public void close() throws SQLException
721721
result = null;
722722
}
723723

724+
/**
725+
* This finalizer ensures that statements that have allocated server-side
726+
* resources free them when they become unreferenced.
727+
*/
728+
protected void finalize() {
729+
try { close(); }
730+
catch (SQLException e) {}
731+
}
732+
724733
/*
725734
* Filter the SQL string of Java SQL Escape clauses.
726735
*
@@ -1088,7 +1097,7 @@ public void setBytes(int parameterIndex, byte x[]) throws SQLException
10881097
}
10891098
else
10901099
{
1091-
setString(parameterIndex, PGbytea.toPGString(x), PG_TEXT);
1100+
setString(parameterIndex, PGbytea.toPGString(x), PG_BYTEA);
10921101
}
10931102
}
10941103
else
@@ -2055,7 +2064,7 @@ public void setUseServerPrepare(boolean flag) throws SQLException {
20552064
if (connection.haveMinimumServerVersion("7.3")) {
20562065
//If turning server prepared statements off deallocate statement
20572066
//and reset statement name
2058-
if (m_useServerPrepare != flag && !flag)
2067+
if (m_useServerPrepare != flag && !flag && m_statementName != null)
20592068
connection.execSQL("DEALLOCATE " + m_statementName);
20602069
m_statementName = null;
20612070
m_useServerPrepare = flag;

src/interfaces/jdbc/org/postgresql/test/jdbc2/ServerPreparedStmtTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,26 @@ public void testPreparedStatementsWithBinds() throws Exception
153153
pstmt.close();
154154
}
155155

156+
public void testSPSToggle() throws Exception
157+
{
158+
// Verify we can toggle UseServerPrepare safely before a query is executed.
159+
PreparedStatement pstmt = con.prepareStatement("SELECT * FROM testsps WHERE id = 2");
160+
((PGStatement)pstmt).setUseServerPrepare(true);
161+
((PGStatement)pstmt).setUseServerPrepare(false);
162+
}
163+
164+
public void testBytea() throws Exception
165+
{
166+
// Verify we can use setBytes() with a server-prepared update.
167+
try {
168+
TestUtil.createTable(con, "testsps_bytea", "data bytea");
169+
170+
PreparedStatement pstmt = con.prepareStatement("INSERT INTO testsps_bytea(data) VALUES (?)");
171+
((PGStatement)pstmt).setUseServerPrepare(true);
172+
pstmt.setBytes(1, new byte[100]);
173+
pstmt.executeUpdate();
174+
} finally {
175+
TestUtil.dropTable(con, "testsps_bytea");
176+
}
177+
}
156178
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy