your JDBC patch

From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: rbulling(at)microstate(dot)com
Cc: PostgreSQL-patches <pgsql-patches(at)postgresql(dot)org>
Subject: your JDBC patch
Date: 2001-01-18 18:56:39
Message-ID: 200101181856.NAA07667@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-patches

We have applied your JDBC patch from yesterday. It is in CVS now, and
will appear in tomorrow's snapshot. Thanks.

---------------------------------------------------------------------------

[Image]

-------------------------------

Fixes and enhancements to JDBC driver (take 2)

-------------------------------

* From: Richard Bullington-McGuire <rbulling(at)microstate(dot)com>
* To: pgsql-patches(at)postgresql(dot)org
* Subject: Fixes and enhancements to JDBC driver (take 2)
* Date: Wed, 17 Jan 2001 14:32:47 -0500 (EST)

------------------------------------------------------------------------

(My apologies, I had attempted to post another message, but it contained a
flawed patch, and it may not even reach the list. If you received that
message, please do not use the attached patch, named
postgres-jdbc-Microstate-fixes.patch. Instead, use the attached patch,
postgres-jdbc-Microstate-fixes-2.patch. Here goes again:)

Please find attached a patch versus the current 7.x source tree from CVS.
It fixes several problems, and adds one new feature.

Here are the problems it fixes:

* org.postgresql.util.PSQLException could generate a null pointer error if
the message was null. I fixed this by checking for a null for message in
addition to checking for null args. This fix is just putting into practice
some defensive programming.

* A serious off-by-one error existed in both of the BytePoolDim classes in
the org.postgresql.PG_Stream class. On a request for a byte pool for the
maximum size, the old code would generate an
ArrayIndexOutOfBoundsException. I fixed this by increasing the size of
the array by one more than the maximum buffer size, and altering the
supporting methods to initialize and clean up the expanded array.

* org.postgresql.jdbc1.ResultSet and org.postgresql.jdbc2.ResultSet
contained several lines where SimpleDateFormat had bad format strings.
The format strings contained "MM", the code for months, instead of
"mm", the code for minutes, in places where the intended result was an
hours:minutes:seconds string.

* utils.CheckVersion version 1.2 failed to compile using the IBM JDK
1.1.8, because of the use of System.setProperty(), a method introduced in
JDK 1.2. I refactored the main method of this class for maximum
portability and clarity. It now supports the IBM JDK 1.1.8, and should
detect other odd 1.1 JDKs more gracefully.

* In utils.CheckVersion, I also removed code that looked like dead code,
at the beginning and end of the main() method. I can't see any reason to
print out the value of the postgresql.jdbc system property when this class
is invoked, nor to set a system property at the end of main(), when
CheckVersion is only used in the make process, and only then for the
version of the driver it sends to System.out.

* If utils.CheckVersion fails to detect a valid JDK version, it returns a
non-zero error code to the calling process, allowing Make to fail
gracefully.

The one enhancement included is a beginning of an implementation for SQL
Escape processing. This implementation implements only the date escape
clause -- we have found in our development that that is the most used of
the escape clauses. The enhancement affects org.postgresql.Connection and
org.postgresql.jdbc1.Statement. The jdbc1.Statement class did not check to
see if escape processing was enabled at all, and the Connection class had
a placeholder implementation of the EscapeSQL() method. At Microstate,
we've been using a variation on this for more than a year in our internal
versions of the PostgreSQL JDBC drivers with great success. The patch
works currently, but it could be made more efficient.

--
Richard Bullington-McGuire <rbulling(at)microstate(dot)com>
Chief Technology Officer, The Microstate Corporation
Phone: 703-796-6446 URL: http://www.microstate.com/
PGP key IDs: RSA: 0x93862305 DH/DSS: 0xDAC3028E

Index: org/postgresql/Connection.java
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Connection.java,v
retrieving revision 1.11
diff -u -3 -r1.11 Connection.java
--- org/postgresql/Connection.java 2000/12/22 03:08:52 1.11
+++ org/postgresql/Connection.java 2001/01/17 19:21:59
@@ -868,10 +868,34 @@
}

/**
- * This is an attempt to implement SQL Escape clauses
+ * Implement SQL Escape clauses.
+ *
+ * <p> This only implements the date escape clause correctly right now.
*/
public String EscapeSQL(String sql) {
- return sql;
+ boolean DEBUG = false;
+ if (DEBUG) { System.out.println ("parseSQLEscapes called"); }
+
+ // If we find a "{d", assume we have a date escape.
+ //
+ // Since the date escape syntax is very close to the
+ // native Postgres date format, we just remove the escape
+ // delimiters.
+ //
+ // This implementation could use some optimization, but it has
+ // worked in practice for two years of solid use.
+ int index = sql.indexOf("{d");
+ while (index != -1) {
+ if (DEBUG) { System.out.println ("escape found at index: " + index);}
+ StringBuffer buf = new StringBuffer(sql);
+ buf.setCharAt(index, ' ');
+ buf.setCharAt(index + 1, ' ');
+ buf.setCharAt(sql.indexOf('}', index), ' ');
+ sql = new String(buf);
+ index = sql.indexOf("{d");
+ }
+ if (DEBUG) { System.out.println ("modified SQL: " + sql); }
+ return sql;
}

}
Index: org/postgresql/PG_Stream.java
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/PG_Stream.java,v
retrieving revision 1.5
diff -u -3 -r1.5 PG_Stream.java
--- org/postgresql/PG_Stream.java 2000/10/12 08:55:24 1.5
+++ org/postgresql/PG_Stream.java 2001/01/17 19:22:00
@@ -494,13 +494,11 @@
*/
class BytePoolDim1 {
int maxsize = 256;
- ObjectPool notusemap[] = new ObjectPool[maxsize];
- ObjectPool inusemap[] = new ObjectPool[maxsize];
- byte binit[][] = new byte[maxsize][0];
+ ObjectPool notusemap[] = new ObjectPool[maxsize + 1];
+ ObjectPool inusemap[] = new ObjectPool[maxsize + 1];

public BytePoolDim1(){
- for(int i = 0; i < maxsize; i++){
- binit[i] = new byte[i];
+ for(int i = 0; i <= maxsize; i++){
inusemap[i] = new ObjectPool();
notusemap[i] = new ObjectPool();
}
@@ -526,7 +524,7 @@
}

public void deallocate(){
- for(int i = 0; i < maxsize; i++){
+ for(int i = 0; i <= maxsize; i++){
notusemap[i].addAll(inusemap[i]);
inusemap[i].clear();
}
@@ -542,11 +540,11 @@
*/
class BytePoolDim2 {
int maxsize = 32;
- ObjectPool notusemap[] = new ObjectPool[maxsize];
- ObjectPool inusemap[] = new ObjectPool[maxsize];
+ ObjectPool notusemap[] = new ObjectPool[maxsize + 1];
+ ObjectPool inusemap[] = new ObjectPool[maxsize + 1];

public BytePoolDim2(){
- for(int i = 0; i < maxsize; i++){
+ for(int i = 0; i <= maxsize; i++){
inusemap[i] = new ObjectPool();
notusemap[i] = new ObjectPool();
}
@@ -571,7 +569,7 @@
}

public void deallocate(){
- for(int i = 0; i < maxsize; i++){
+ for(int i = 0; i <= maxsize; i++){
notusemap[i].addAll(inusemap[i]);
inusemap[i].clear();
}
Index: org/postgresql/jdbc1/ResultSet.java
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/ResultSet.java,v
retrieving revision 1.8
diff -u -3 -r1.8 ResultSet.java
--- org/postgresql/jdbc1/ResultSet.java 2001/01/13 18:52:42 1.8
+++ org/postgresql/jdbc1/ResultSet.java 2001/01/17 19:22:00
@@ -471,12 +471,12 @@
SimpleDateFormat df = null;
if (s.length()>21 && s.indexOf('.') != -1) {
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSzzz");
- } else if (s.length()>19 && s.indexOf('.') == -1) {
- df = new SimpleDateFormat("yyyy-MM-dd HH:MM:sszzz");
- } else if (s.length()>19 && s.indexOf('.') != -1) {
- df = new SimpleDateFormat("yyyy-MM-dd HH:MM:ss.SS");
- } else if (s.length()>10 && s.length()<=18) {
- df = new SimpleDateFormat("yyyy-MM-dd HH:MM:ss");
+ } else if (s.length()>19 && s.indexOf('.') == -1) {
+ df = new SimpleDateFormat("yyyy-MM-dd HH:mm:sszzz");
+ } else if (s.length()>19 && s.indexOf('.') != -1) {
+ df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SS");
+ } else if (s.length()>10) {
+ df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
} else {
df = new SimpleDateFormat("yyyy-MM-dd");
}
Index: org/postgresql/jdbc1/Statement.java
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java,v
retrieving revision 1.3
diff -u -3 -r1.3 Statement.java
--- org/postgresql/jdbc1/Statement.java 2000/10/09 16:48:17 1.3
+++ org/postgresql/jdbc1/Statement.java 2001/01/17 19:22:00
@@ -266,6 +266,8 @@
*/
public boolean execute(String sql) throws SQLException
{
+ if (escapeProcessing)
+ sql = connection.EscapeSQL(sql);
result = connection.ExecSQL(sql);
return (result != null && ((org.postgresql.ResultSet)result).reallyResultSet());
}
Index: org/postgresql/jdbc2/ResultSet.java
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java,v
retrieving revision 1.15
diff -u -3 -r1.15 ResultSet.java
--- org/postgresql/jdbc2/ResultSet.java 2001/01/13 18:52:42 1.15
+++ org/postgresql/jdbc2/ResultSet.java 2001/01/17 19:22:02
@@ -486,11 +486,11 @@
if (s.length()>21 && s.indexOf('.') != -1) {
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSzzz");
} else if (s.length()>19 && s.indexOf('.') == -1) {
- df = new SimpleDateFormat("yyyy-MM-dd HH:MM:sszzz");
+ df = new SimpleDateFormat("yyyy-MM-dd HH:mm:sszzz");
} else if (s.length()>19 && s.indexOf('.') != -1) {
- df = new SimpleDateFormat("yyyy-MM-dd HH:MM:ss.SS");
+ df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SS");
} else if (s.length()>10 && s.length()<=18) {
- df = new SimpleDateFormat("yyyy-MM-dd HH:MM:ss");
+ df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
} else {
df = new SimpleDateFormat("yyyy-MM-dd");
}
Index: org/postgresql/util/PSQLException.java
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/util/PSQLException.java,v
retrieving revision 1.2
diff -u -3 -r1.2 PSQLException.java
--- org/postgresql/util/PSQLException.java 2000/09/12 05:18:25 1.2
+++ org/postgresql/util/PSQLException.java 2001/01/17 19:22:02
@@ -83,7 +83,7 @@
}

// Expand any arguments
- if(args!=null)
+ if(args != null && message != null)
message = MessageFormat.format(message,args);

}
Index: utils/CheckVersion.java
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/jdbc/utils/CheckVersion.java,v
retrieving revision 1.2
diff -u -3 -r1.2 CheckVersion.java
--- utils/CheckVersion.java 2000/12/19 17:33:39 1.2
+++ utils/CheckVersion.java 2001/01/17 19:22:02
@@ -1,5 +1,7 @@
package utils;

+import java.util.Properties;
+
/**
* This little app checks to see what version of JVM is being used.
* It does this by checking first the java.vm.version property, and
@@ -41,28 +43,30 @@
{
String vmversion = System.getProperty("java.vm.version");

- System.out.println("postgresql.jdbc="+System.getProperty("postgresql.jdbc"));
-
- // We are running a 1.1 JVM
- if(vmversion.startsWith("1.1")) {
+ // We might be running a 1.1 JDK that does not define
+ // vmversion, such as the IBM JDK 1.1.8
+ if(vmversion == null && checkClass("java.lang.Byte")) {
System.out.println("jdbc1");
- //System.exit(0);
- }
- else
- // We are running a 1.2 or 1.3 JVM
- if(vmversion.startsWith("1.2") ||
- vmversion.startsWith("1.3") ||
- checkClass("java.lang.Byte")
- ) {
-
+ }
+ // We are running a 1.1 JDK
+ else if (vmversion.startsWith("1.1")) {
+ System.out.println("jdbc1");
+ }
+ // We are running a 1.2 or 1.3 JDK, or maybe another
+ // compatible JDK that has java.lang.Byte support.
+ else if(vmversion.startsWith("1.2") ||
+ vmversion.startsWith("1.3") ||
+ checkClass("java.lang.Byte")
+ ) {
// Check to see if we have the standard extensions. If so, then
// we want the enterprise edition, otherwise the jdbc2 driver.
if(checkClass("javax.sql.DataSource"))
- System.out.println("enterprise");
+ System.out.println("enterprise");
else
- System.out.println("jdbc2");
- //System.exit(0);
+ System.out.println("jdbc2");
}
- System.setProperty("postgresql.jdbc","yoyo");
+ // If we have not detected a supported JDK version,
+ // exit with an error status to stop the make process early.
+ else System.exit(1);
}
}

------------------------------------------------------------------------

* Prev by Date: Re: [INTERFACES] Patch for JDBC timestamp problems
* Next by Date: Re: patch for src/backend/port/darwin/sem.c
* Next by thread: Patch for jdbc Makefile
* Index(es):
o Date
o Thread

Home | Main Index | Thread Index

--
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 853-3000
+ If your life is a hard drive, | 830 Blythe Avenue
+ Christ can be your backup. | Drexel Hill, Pennsylvania 19026

Responses

Browse pgsql-patches by date

  From Date Subject
Next Message Richard Bullington-McGuire 2001-01-18 21:40:44 Re: your JDBC patch
Previous Message Gunnar R|nning 2001-01-18 13:49:23 Re: Fixes and enhancements to JDBC driver (take 2)