Postgresql JDBC Timestamp problem

Поиск
Список
Период
Сортировка
От Veit Guna
Тема Postgresql JDBC Timestamp problem
Дата
Msg-id 3CD2A952.2000604@xionet.de
обсуждение исходный текст
Список pgsql-bugs
Hi.

We're using a Postgresql 7.2 Database through the appropriate jdbc
driver with Java 2.

Selecting Data, updating etc. works fine except for the getTimestamp()
method on the ResultSet. It delivers only a 3 digit fraction, although
there's a 6 digit fraction stored in the db (timestamptz column, filled
by now()). The following sequence will consquential fail:

- select timestamp as ts, data from table
- update table set data = 'new data' where timestamp = ts

using PreparedStatements.

We took a look at the JDBC2 implementation of this method. It says
something about java could not store more than a 3 digit fraction.
That's not entirely true. We used the HEAD version of the jdbc driver
from your repository to create a "workaround" that could fix this
problem. Please take a look at the attached ResultSet patch which will
allow a 6 digit fraction. Take this patch only as an idea how the
problem could be solved. It works so far...

Thank you for your patience...


ps.: if this fix will be published, please mention that Stefan Jantzon
has developed this fix mainly 8)...
--
"...$HOME is where cd takes you..."
Index: ResultSet.java
===================================================================
RCS file: /projects/cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java,v
retrieving revision 1.51
diff -u -r1.51 ResultSet.java
--- ResultSet.java    2002/03/27 05:33:27    1.51
+++ ResultSet.java    2002/05/03 14:34:33
@@ -1598,13 +1598,9 @@
     /**
     * Parse a string and return a timestamp representing its value.
     *
-    * The driver is set to return ISO date formated strings. We modify this
+    * The driver is set to return ISO date formated strings. We modify this
     * string from the ISO format to a format that Java can understand. Java
     * expects timezone info as 'GMT+09:00' where as ISO gives '+09'.
-    * Java also expects fractional seconds to 3 places where postgres
-    * will give, none, 2 or 6 depending on the time and postgres version.
-    * From version 7.2 postgres returns fractional seconds to 6 places.
-    * If available, we drop the last 3 digits.
     *
     * @param s         The ISO formated date string to parse.
     * @param resultSet The ResultSet this date is part of.
@@ -1626,6 +1622,9 @@
         {
             SimpleDateFormat df = null;

+                        // used to store the complete fraction
+                        StringBuffer frac = new StringBuffer("000000000");
+
             // If first time, create the buffer, otherwise clear it.
             if (resultSet.sbuf == null)
                 resultSet.sbuf = new StringBuffer();
@@ -1649,25 +1648,19 @@
                 char c = s.charAt(i++);
                 if (c == '.')
                 {
-                    // Found a fractional value. Append up to 3 digits including
-                    // the leading '.'
-                    do
-                    {
-                        if (i < 24)
-                            resultSet.sbuf.append(c);
-                        c = s.charAt(i++);
-                    } while (i < slen && Character.isDigit(c));
-
-                    // If there wasn't at least 3 digits we should add some zeros
-                    // to make up the 3 digits we tell java to expect.
-                    for (int j = i; j < 24; j++)
-                        resultSet.sbuf.append('0');
+                                        // Found a fractional value. Save it for later use.
+                                        int pos=0;
+                                        while ( i < slen) {
+                                                c = s.charAt(i);
+                                                i++;
+                                                if (Character.isDigit(c)) {
+                                                    frac.setCharAt(pos,c);
+                                                    pos++;
+                                                } else {
+                                                    break;
+                                                }
+                                        }
                 }
-                else
-                {
-                    // No fractional seconds, lets add some.
-                    resultSet.sbuf.append(".000");
-                }

                 if (i < slen)
                 {
@@ -1683,17 +1676,17 @@
                         resultSet.sbuf.append(":00");

                     // we'll use this dateformat string to parse the result.
-                    df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z");
+                    df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
                 }
                 else
                 {
-                    // Just found fractional seconds but no timezone.
-                    df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+                    // dateformat this string - no timezone.
+                    df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                 }
             }
             else if (slen == 19)
             {
-                // No tz or fractional second info.
+                // No tz or fractional second info.
                 // I'm not sure if it is
                 // possible to have a string in this format, as pg
                 // should give us tz qualified timestamps back, but it was
@@ -1702,7 +1695,7 @@
             }
             else
             {
-                // We must just have a date. This case is
+                // We must just have a date. This case is
                 // needed if this method is called on a date
                 // column
                 df = new SimpleDateFormat("yyyy-MM-dd");
@@ -1711,7 +1704,10 @@
             try
             {
                 // All that's left is to parse the string and return the ts.
-                return new Timestamp(df.parse(resultSet.sbuf.toString()).getTime());
+                                // Set the fraction, saved from above.
+                                Timestamp ts = new Timestamp(df.parse(resultSet.sbuf.toString()).getTime());
+                                ts.setNanos(Integer.parseInt(frac.toString()));
+                                return ts;
             }
             catch (ParseException e)
             {
@@ -1720,4 +1716,3 @@
         }
     }
 }
-

В списке pgsql-bugs по дате отправления:

Предыдущее
От: "Rob Butler"
Дата:
Сообщение: PQescapeString and PQescapeBytea not exported during win 32 build
Следующее
От: Hans Plum
Дата:
Сообщение: Bug in functions lower(), upper() with SQL_ASCII and LATIN1?