db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kahat...@apache.org
Subject svn commit: r938547 - in /db/derby/code/trunk/java: client/org/apache/derby/client/am/ testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/
Date Tue, 27 Apr 2010 16:34:47 GMT
Author: kahatlen
Date: Tue Apr 27 16:34:46 2010
New Revision: 938547

URL: http://svn.apache.org/viewvc?rev=938547&view=rev
Log:
DERBY-4582: Timestamps inserted with GMT calendar are 1 hour later
when subsequently read with GMT calendar (Server Mode Only)

Last patch for this issue. Now the Calendar objects passed to the
getters in ResultSet and CallableStatement are passed further down to
where the parsing of the values from the server happens.

Modified:
    db/derby/code/trunk/java/client/org/apache/derby/client/am/CallableStatement.java
    db/derby/code/trunk/java/client/org/apache/derby/client/am/CrossConverters.java
    db/derby/code/trunk/java/client/org/apache/derby/client/am/Cursor.java
    db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/_Suite.java

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/CallableStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/CallableStatement.java?rev=938547&r1=938546&r2=938547&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/CallableStatement.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/CallableStatement.java Tue
Apr 27 16:34:46 2010
@@ -25,7 +25,11 @@ import org.apache.derby.client.ClientPoo
 import org.apache.derby.shared.common.reference.SQLState;
 
 import java.io.Reader;
+import java.sql.Date;
 import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
 
 public class CallableStatement extends PreparedStatement
         implements java.sql.PreparedStatement,
@@ -461,17 +465,26 @@ public class CallableStatement extends P
         }
     }
 
-    public java.sql.Date getDate(int parameterIndex) throws SQLException {
+    public Date getDate(int parameterIndex, Calendar cal) throws SQLException {
         try
         {
             synchronized (connection_) {
                 if (agent_.loggingEnabled()) {
-                    agent_.logWriter_.traceEntry(this, "getDate", parameterIndex);
+                    agent_.logWriter_.traceEntry(
+                            this, "getDate", parameterIndex, cal);
                 }
                 super.checkForClosedStatement();
                 checkGetterPreconditions(parameterIndex);
+
+                if (cal == null) {
+                    throw new SqlException(agent_.logWriter_,
+                        new ClientMessageId(SQLState.CALENDAR_IS_NULL));
+                }
+
                 setWasNull(parameterIndex);
-                java.sql.Date result = wasNullX() ? null : singletonRowData_.getDate(parameterIndex);
+                Date result = wasNullX() ?
+                        null :
+                        singletonRowData_.getDate(parameterIndex, cal);
                 if (agent_.loggingEnabled()) {
                     agent_.logWriter_.traceExit(this, "getDate", result);
                 }
@@ -484,47 +497,30 @@ public class CallableStatement extends P
         }
     }
 
-    public java.sql.Date getDate(int parameterIndex, java.util.Calendar cal) throws SQLException
{
-        synchronized (connection_) {
-            if (agent_.loggingEnabled()) {
-                agent_.logWriter_.traceEntry(this, "getDate", parameterIndex, cal);
-            }
-            java.sql.Date result = getDate(parameterIndex);
-            if (cal == null) {
-                throw new SqlException(agent_.logWriter_, 
-                    new ClientMessageId(SQLState.CALENDAR_IS_NULL)).getSQLException();
-            }
-            if (result != null) {
-                java.util.Calendar targetCalendar = java.util.Calendar.getInstance(cal.getTimeZone());
-                targetCalendar.clear();
-                targetCalendar.setTime(result);
-                java.util.Calendar defaultCalendar = java.util.Calendar.getInstance();
-                defaultCalendar.clear();
-
-                defaultCalendar.setTime(result);
-                long timeZoneOffset =
-                        targetCalendar.get(java.util.Calendar.ZONE_OFFSET) - defaultCalendar.get(java.util.Calendar.ZONE_OFFSET)
+
-                        targetCalendar.get(java.util.Calendar.DST_OFFSET) - defaultCalendar.get(java.util.Calendar.DST_OFFSET);
-                result.setTime(result.getTime() - timeZoneOffset);
-            }
-            if (agent_.loggingEnabled()) {
-                agent_.logWriter_.traceExit(this, "getDate", result);
-            }
-            return result;
-        }
+    public Date getDate(int parameterIndex) throws SQLException {
+        return getDate(parameterIndex, Calendar.getInstance());
     }
 
-    public java.sql.Time getTime(int parameterIndex) throws SQLException {
+    public Time getTime(int parameterIndex, Calendar cal) throws SQLException {
         try
         {
             synchronized (connection_) {
                 if (agent_.loggingEnabled()) {
-                    agent_.logWriter_.traceEntry(this, "getTime", parameterIndex);
+                    agent_.logWriter_.traceEntry(
+                            this, "getTime", parameterIndex, cal);
                 }
                 super.checkForClosedStatement();
                 checkGetterPreconditions(parameterIndex);
+
+                if (cal == null) {
+                    throw new SqlException(agent_.logWriter_,
+                        new ClientMessageId(SQLState.CALENDAR_IS_NULL));
+                }
+
                 setWasNull(parameterIndex);
-                java.sql.Time result = wasNullX() ? null : singletonRowData_.getTime(parameterIndex);
+                Time result = wasNullX() ?
+                        null :
+                        singletonRowData_.getTime(parameterIndex, cal);
                 if (agent_.loggingEnabled()) {
                     agent_.logWriter_.traceExit(this, "getTime", result);
                 }
@@ -537,46 +533,31 @@ public class CallableStatement extends P
         }
     }
 
-    public java.sql.Time getTime(int parameterIndex, java.util.Calendar cal) throws SQLException
{
-        synchronized (connection_) {
-            if (agent_.loggingEnabled()) {
-                agent_.logWriter_.traceEntry(this, "getTime", parameterIndex, cal);
-            }
-            java.sql.Time result = getTime(parameterIndex);
-            if (cal == null) {
-                throw new SqlException(agent_.logWriter_, 
-                    new ClientMessageId(SQLState.CALENDAR_IS_NULL)).getSQLException();
-            }
-            if (result != null) {
-                java.util.Calendar targetCalendar = java.util.Calendar.getInstance(cal.getTimeZone());
-                targetCalendar.clear();
-                targetCalendar.setTime(result);
-                java.util.Calendar defaultCalendar = java.util.Calendar.getInstance();
-                defaultCalendar.clear();
-                defaultCalendar.setTime(result);
-                long timeZoneOffset =
-                        targetCalendar.get(java.util.Calendar.ZONE_OFFSET) - defaultCalendar.get(java.util.Calendar.ZONE_OFFSET)
+
-                        targetCalendar.get(java.util.Calendar.DST_OFFSET) - defaultCalendar.get(java.util.Calendar.DST_OFFSET);
-                result.setTime(result.getTime() - timeZoneOffset);
-            }
-            if (agent_.loggingEnabled()) {
-                agent_.logWriter_.traceExit(this, "getTime", result);
-            }
-            return result;
-        }
+    public Time getTime(int parameterIndex) throws SQLException {
+        return getTime(parameterIndex, Calendar.getInstance());
     }
 
-    public java.sql.Timestamp getTimestamp(int parameterIndex) throws SQLException {
+    public Timestamp getTimestamp(int parameterIndex, Calendar cal)
+            throws SQLException {
         try
         {
             synchronized (connection_) {
                 if (agent_.loggingEnabled()) {
-                    agent_.logWriter_.traceEntry(this, "getTimestamp", parameterIndex);
+                    agent_.logWriter_.traceEntry(
+                            this, "getTimestamp", parameterIndex, cal);
                 }
                 super.checkForClosedStatement();
                 checkGetterPreconditions(parameterIndex);
+
+                if (cal == null) {
+                    throw new SqlException(agent_.logWriter_,
+                        new ClientMessageId(SQLState.CALENDAR_IS_NULL));
+                }
+
                 setWasNull(parameterIndex);
-                java.sql.Timestamp result = wasNullX() ? null : singletonRowData_.getTimestamp(parameterIndex);
+                Timestamp result = wasNullX() ?
+                        null :
+                        singletonRowData_.getTimestamp(parameterIndex, cal);
                 if (agent_.loggingEnabled()) {
                     agent_.logWriter_.traceExit(this, "getTimestamp", result);
                 }
@@ -589,35 +570,8 @@ public class CallableStatement extends P
         }
     }
 
-    public java.sql.Timestamp getTimestamp(int parameterIndex, java.util.Calendar cal) throws
SQLException {
-        synchronized (connection_) {
-            if (agent_.loggingEnabled()) {
-                agent_.logWriter_.traceEntry(this, "getTimestamp", parameterIndex, cal);
-            }
-            java.sql.Timestamp result = getTimestamp(parameterIndex);
-            if (cal == null) {
-                throw new SqlException(agent_.logWriter_, 
-                    new ClientMessageId(SQLState.CALENDAR_IS_NULL)).getSQLException();
-            }
-            if (result != null) {
-                int nano = result.getNanos();
-                java.util.Calendar targetCalendar = java.util.Calendar.getInstance(cal.getTimeZone());
-                targetCalendar.clear();
-                targetCalendar.setTime(result);
-                java.util.Calendar defaultCalendar = java.util.Calendar.getInstance();
-                defaultCalendar.clear();
-                defaultCalendar.setTime(result);
-                long timeZoneOffset =
-                        targetCalendar.get(java.util.Calendar.ZONE_OFFSET) - defaultCalendar.get(java.util.Calendar.ZONE_OFFSET)
+
-                        targetCalendar.get(java.util.Calendar.DST_OFFSET) - defaultCalendar.get(java.util.Calendar.DST_OFFSET);
-                result.setTime(result.getTime() - timeZoneOffset);
-                result.setNanos(nano);
-            }
-            if (agent_.loggingEnabled()) {
-                agent_.logWriter_.traceExit(this, "getTimestamp", result);
-            }
-            return result;
-        }
+    public Timestamp getTimestamp(int parameterIndex) throws SQLException {
+        return getTimestamp(parameterIndex, Calendar.getInstance());
     }
 
     public String getString(int parameterIndex) throws SQLException {

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/CrossConverters.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/CrossConverters.java?rev=938547&r1=938546&r2=938547&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/CrossConverters.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/CrossConverters.java Tue Apr
27 16:34:46 2010
@@ -21,6 +21,10 @@
 
 package org.apache.derby.client.am;
 
+import java.sql.Date;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
 import org.apache.derby.shared.common.reference.SQLState;
 
 // All currently supported derby types are mapped to one of the following jdbc types:
@@ -558,13 +562,13 @@ final class CrossConverters {
                 return new java.math.BigDecimal(source);
 
             case java.sql.Types.DATE:
-                return date_valueOf(source);
+                return date_valueOf(source, null);
 
             case java.sql.Types.TIME:
-                return time_valueOf(source);
+                return time_valueOf(source, null);
 
             case java.sql.Types.TIMESTAMP:
-                return timestamp_valueOf(source);
+                return timestamp_valueOf(source, null);
 
             case Types.CHAR:
             case Types.VARCHAR:
@@ -1221,9 +1225,10 @@ final class CrossConverters {
 
     //---------------------------- getDate*() methods ----------------------------
 
-    final java.sql.Date getDateFromString(String source) throws SqlException {
+    final Date getDateFromString(String source, Calendar cal)
+            throws SqlException {
         try {
-            return date_valueOf(source);
+            return date_valueOf(source, cal);
         } catch (java.lang.IllegalArgumentException e) { // subsumes NumberFormatException
             throw new SqlException(agent_.logWriter_, 
             		new ClientMessageId (SQLState.LANG_DATE_SYNTAX_EXCEPTION), e);
@@ -1240,9 +1245,10 @@ final class CrossConverters {
 
     //---------------------------- getTime*() methods ----------------------------
 
-    final java.sql.Time getTimeFromString(String source) throws SqlException {
+    final Time getTimeFromString(String source, Calendar cal)
+            throws SqlException {
         try {
-            return time_valueOf(source);
+            return time_valueOf(source, cal);
         } catch (java.lang.IllegalArgumentException e) { // subsumes NumberFormatException
             throw new SqlException(agent_.logWriter_, 
             		new ClientMessageId (SQLState.LANG_DATE_SYNTAX_EXCEPTION), e);
@@ -1255,9 +1261,10 @@ final class CrossConverters {
 
     //---------------------------- getTimestamp*() methods -----------------------
 
-    final java.sql.Timestamp getTimestampFromString(String source) throws SqlException {
+    final Timestamp getTimestampFromString(String source, Calendar cal)
+            throws SqlException {
         try {
-            return timestamp_valueOf(source);
+            return timestamp_valueOf(source, cal);
         } catch (java.lang.IllegalArgumentException e) {  // subsumes NumberFormatException
             throw new SqlException(agent_.logWriter_, 
             		new ClientMessageId (SQLState.LANG_DATE_SYNTAX_EXCEPTION), e);
@@ -1272,33 +1279,209 @@ final class CrossConverters {
         return new java.sql.Timestamp(source.getTime());
     }
 
-    final java.sql.Date date_valueOf(String s) throws java.lang.IllegalArgumentException
{
+    /**
+     * Convert a string to a date in the specified calendar. Accept the same
+     * format as {@code java.sql.Date.valueOf()}.
+     *
+     * @param s the string to parse
+     * @param cal the calendar (or null to use the default calendar)
+     * @return a {@code java.sql.Date} value that represents the date in the
+     * calendar {@code cal}
+     * @throws IllegalArgumentException if the format of the string is invalid
+     */
+    final Date date_valueOf(String s, Calendar cal) {
         String formatError = "JDBC Date format must be yyyy-mm-dd";
         if (s == null) {
             throw new java.lang.IllegalArgumentException(formatError);
         }
         s = s.trim();
-        return java.sql.Date.valueOf(s);
+
+        if (cal == null) {
+            return Date.valueOf(s);
+        }
+
+        cal.clear();
+        initDatePortion(cal, s);
+
+        // Normalize time components as specified by java.util.Date.
+        cal.set(Calendar.HOUR_OF_DAY, 0);
+        cal.set(Calendar.MINUTE, 0);
+        cal.set(Calendar.SECOND, 0);
+        cal.set(Calendar.MILLISECOND, 0);
+
+        return new Date(cal.getTimeInMillis());
+    }
+
+    /**
+     * Initialize the date components of a {@code java.util.Calendar} from
+     * a string on the format YYYY-MM-DD. All other components are left
+     * untouched.
+     *
+     * @param cal the calendar whose date components to initialize
+     * @param date a string representing a date
+     * @throws IllegalArgumentException if the date string is not on the
+     * format YYYY-MM-DD
+     */
+    private static void initDatePortion(Calendar cal, String date) {
+
+        // Expect string on format YYYY-MM-DD
+        if (date.length() != 10 ||
+                date.charAt(4) != '-' || date.charAt(7) != '-') {
+            throw new IllegalArgumentException();
+        }
+
+        int year =
+                digit(date.charAt(0)) * 1000 +
+                digit(date.charAt(1)) * 100 +
+                digit(date.charAt(2)) * 10 +
+                digit(date.charAt(3));
+
+        int month =
+                digit(date.charAt(5)) * 10 +
+                digit(date.charAt(6));
+
+        int day =
+                digit(date.charAt(8)) * 10 +
+                digit(date.charAt(9));
+
+        cal.set(year, month, day);
     }
 
+    /**
+     * Convert a character to a digit.
+     *
+     * @param ch the character
+     * @return the corresponding digit (0-9)
+     * @throws IllegalArgumentException if {@code ch} doesn't represent a digit
+     */
+    private static int digit(char ch) {
+        int result = Character.digit(ch, 10);
+        if (result == -1) {
+            throw new IllegalArgumentException();
+        }
+        return result;
+    }
 
-    final java.sql.Time time_valueOf(String s) throws java.lang.IllegalArgumentException,
NumberFormatException {
+    /**
+     * Convert a string to a time in the specified calendar. Accept the same
+     * format as {@code java.sql.Time.valueOf()}.
+     *
+     * @param s the string to parse
+     * @param cal the calendar (or null to use the default calendar)
+     * @return a {@code java.sql.Time} value that represents the time in the
+     * calendar {@code cal}
+     * @throws IllegalArgumentException if the format of the string is invalid
+     */
+    final Time time_valueOf(String s, Calendar cal) {
         String formatError = "JDBC Time format must be hh:mm:ss";
         if (s == null) {
             throw new java.lang.IllegalArgumentException();
         }
         s = s.trim();
-        return java.sql.Time.valueOf(s);
+
+        if (cal == null) {
+            return Time.valueOf(s);
+        }
+
+        cal.clear();
+        initTimePortion(cal, s);
+
+        // Normalize date components as specified by java.sql.Time.
+        cal.set(1970, Calendar.JANUARY, 1);
+
+        return new Time(cal.getTimeInMillis());
     }
 
-    final java.sql.Timestamp timestamp_valueOf(String s) throws java.lang.IllegalArgumentException,
NumberFormatException {
+    /**
+     * Initialize the time components of a {@code java.util.Calendar} from a
+     * string on the format HH:MM:SS. All other components are left untouched.
+     *
+     * @param cal the calendar whose time components to initialize
+     * @param time a string representing a time
+     * @throws IllegalArgumentException if the time string is not on the
+     * format HH:MM:SS
+     */
+    private void initTimePortion(Calendar cal, String time) {
+        // Expect string on format HH:MM:SS
+        if (time.length() != 8 ||
+                time.charAt(2) != ':' || time.charAt(5) != ':') {
+            throw new IllegalArgumentException();
+        }
+
+        int hour = digit(time.charAt(0)) * 10 + digit(time.charAt(1));
+        int minute = digit(time.charAt(3)) * 10 + digit(time.charAt(4));
+        int second = digit(time.charAt(6)) * 10 + digit(time.charAt(7));
+
+        cal.set(Calendar.HOUR_OF_DAY, hour);
+        cal.set(Calendar.MINUTE, minute);
+        cal.set(Calendar.SECOND, second);
+    }
+
+    /**
+     * Convert a string to a timestamp in the specified calendar. Accept the
+     * same format as {@code java.sql.Timestamp.valueOf()}.
+     *
+     * @param s the string to parse
+     * @param cal the calendar (or null to use the default calendar)
+     * @return a {@code java.sql.Timestamp} value that represents the timestamp
+     * in the calendar {@code cal}
+     * @throws IllegalArgumentException if the format of the string is invalid
+     */
+    final Timestamp timestamp_valueOf(String s, Calendar cal) {
         String formatError = "JDBC Timestamp format must be yyyy-mm-dd hh:mm:ss.fffffffff";
         if (s == null) {
             throw new java.lang.IllegalArgumentException();
         }
 
         s = s.trim();
-        return java.sql.Timestamp.valueOf(s);
+
+        if (cal == null) {
+            return Timestamp.valueOf(s);
+        }
+
+        cal.clear();
+
+        // Split into date and time components
+        String[] dateAndTime = s.split(" ");
+        if (dateAndTime.length != 2) {
+            throw new IllegalArgumentException();
+        }
+
+        String dateString = dateAndTime[0];
+        String timeAndNanoString = dateAndTime[1];
+
+        initDatePortion(cal, dateString);
+
+        // Split the time and nano components. The nano component is optional,
+        // and is separated from the time component with a decimal point.
+        String[] timeAndNanos = timeAndNanoString.split("\\.");
+        if (timeAndNanos.length < 1 || timeAndNanos.length > 2) {
+            throw new IllegalArgumentException();
+        }
+
+        String timeString = timeAndNanos[0];
+
+        initTimePortion(cal, timeString);
+
+        int nanos = 0;
+        if (timeAndNanos.length > 1) {
+            String nanoString = timeAndNanos[1];
+            int extraZeros = 9 - nanoString.length();
+            if (extraZeros < 0) {
+                throw new IllegalArgumentException();
+            }
+            // parseInt() may throw NumberFormatException. NFE is a subclass
+            // of IllegalArgumentException, so no need to document separately
+            // in the javadoc.
+            nanos = Integer.parseInt(nanoString);
+            for (int i = 0; i < extraZeros; i++) {
+                nanos *= 10;
+            }
+        }
+
+        Timestamp ts = new Timestamp(cal.getTimeInMillis());
+        ts.setNanos(nanos);
+        return ts;
     }
 
     private final byte parseByte(String s) throws NumberFormatException {

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/Cursor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/Cursor.java?rev=938547&r1=938546&r2=938547&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/Cursor.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/Cursor.java Tue Apr 27 16:34:46
2010
@@ -28,6 +28,9 @@ import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.ObjectInputStream;
 import java.io.UnsupportedEncodingException;
+import java.sql.Date;
+import java.sql.Time;
+import java.util.Calendar;
 
 // When we calculate column offsets make sure we calculate the correct offsets for double
byte charactr5er data
 // length from server is number of chars, not bytes
@@ -509,11 +512,11 @@ public abstract class Cursor {
     }
 
     // Build a JDBC Date object from the DERBY ISO DATE field.
-    private final java.sql.Date getDATE(int column) throws SqlException {
+    private final Date getDATE(int column, Calendar cal) throws SqlException {
         try {
             return org.apache.derby.client.am.DateTime.dateBytesToDate(dataBuffer_,
                 columnDataPosition_[column - 1],
-                getRecyclableCalendar(), 
+                cal,
                 charsetName_[column - 1]);
         }catch (UnsupportedEncodingException e) {
              throw new SqlException(agent_.logWriter_, 
@@ -525,11 +528,11 @@ public abstract class Cursor {
     }
 
     // Build a JDBC Time object from the DERBY ISO TIME field.
-    private final java.sql.Time getTIME(int column) throws SqlException {
+    private final Time getTIME(int column, Calendar cal) throws SqlException {
         try {
             return org.apache.derby.client.am.DateTime.timeBytesToTime(dataBuffer_,
                     columnDataPosition_[column - 1],
-                    getRecyclableCalendar(),
+                    cal,
                     charsetName_[column - 1]);
         } catch (UnsupportedEncodingException e) {
              throw new SqlException(agent_.logWriter_, 
@@ -539,13 +542,14 @@ public abstract class Cursor {
     }
 
     // Build a JDBC Timestamp object from the DERBY ISO TIMESTAMP field.
-    private final java.sql.Timestamp getTIMESTAMP(int column) throws SqlException {
+    private final java.sql.Timestamp getTIMESTAMP(int column, Calendar cal)
+            throws SqlException {
 
         try {
             return org.apache.derby.client.am.DateTime.timestampBytesToTimestamp(
                 dataBuffer_,
                 columnDataPosition_[column - 1],
-                getRecyclableCalendar(), 
+                cal,
                 charsetName_[column - 1],
                 agent_.connection_.serverSupportsTimestampNanoseconds());
     } catch (java.io.UnsupportedEncodingException e) {
@@ -556,11 +560,12 @@ public abstract class Cursor {
     }
 
     // Build a JDBC Timestamp object from the DERBY ISO DATE field.
-    private final java.sql.Timestamp getTimestampFromDATE(int column) throws SqlException
{
+    private final java.sql.Timestamp getTimestampFromDATE(
+            int column, Calendar cal) throws SqlException {
         try {
             return org.apache.derby.client.am.DateTime.dateBytesToTimestamp(dataBuffer_,
                     columnDataPosition_[column - 1],
-                    getRecyclableCalendar(), 
+                    cal,
                     charsetName_[column -1]);
         } catch (UnsupportedEncodingException e) {
              throw new SqlException(agent_.logWriter_, 
@@ -570,11 +575,12 @@ public abstract class Cursor {
     }
 
     // Build a JDBC Timestamp object from the DERBY ISO TIME field.
-    private final java.sql.Timestamp getTimestampFromTIME(int column) throws SqlException
{
+    private final java.sql.Timestamp getTimestampFromTIME(
+            int column, Calendar cal) throws SqlException {
         try {
             return org.apache.derby.client.am.DateTime.timeBytesToTimestamp(dataBuffer_,
                     columnDataPosition_[column - 1],
-                    getRecyclableCalendar(),
+                    cal,
                     charsetName_[column -1]);
         } catch (UnsupportedEncodingException e) {
              throw new SqlException(agent_.logWriter_, 
@@ -584,11 +590,12 @@ public abstract class Cursor {
     }
 
     // Build a JDBC Date object from the DERBY ISO TIMESTAMP field.
-    private final java.sql.Date getDateFromTIMESTAMP(int column) throws SqlException {
+    private final java.sql.Date getDateFromTIMESTAMP(int column, Calendar cal)
+            throws SqlException {
         try {
             return org.apache.derby.client.am.DateTime.timestampBytesToDate(dataBuffer_,
                     columnDataPosition_[column - 1],
-                    getRecyclableCalendar(),
+                    cal,
                     charsetName_[column -1]);
         } catch (UnsupportedEncodingException e) {
              throw new SqlException(agent_.logWriter_, 
@@ -598,11 +605,12 @@ public abstract class Cursor {
     }
 
     // Build a JDBC Time object from the DERBY ISO TIMESTAMP field.
-    private final java.sql.Time getTimeFromTIMESTAMP(int column) throws SqlException {
+    private final java.sql.Time getTimeFromTIMESTAMP(int column, Calendar cal)
+            throws SqlException {
         try {
             return org.apache.derby.client.am.DateTime.timestampBytesToTime(dataBuffer_,
                     columnDataPosition_[column - 1],
-                    getRecyclableCalendar(),
+                    cal,
                     charsetName_[column -1]);
         } catch (UnsupportedEncodingException e) {
              throw new SqlException(agent_.logWriter_, 
@@ -612,17 +620,17 @@ public abstract class Cursor {
     }
 
     private final String getStringFromDATE(int column) throws SqlException {
-        return getDATE(column).toString();
+        return getDATE(column, getRecyclableCalendar()).toString();
     }
 
     // Build a string object from the DERBY byte TIME representation.
     private final String getStringFromTIME(int column) throws SqlException {
-        return getTIME(column).toString();
+        return getTIME(column, getRecyclableCalendar()).toString();
     }
 
     // Build a string object from the DERBY byte TIMESTAMP representation.
     private final String getStringFromTIMESTAMP(int column) throws SqlException {
-        return getTIMESTAMP(column).toString();
+        return getTIMESTAMP(column, getRecyclableCalendar()).toString();
     }
 
     // Extract bytes from a database java.sql.Types.BINARY field.
@@ -967,53 +975,60 @@ public abstract class Cursor {
         }
     }
 
-    final java.sql.Date getDate(int column) throws SqlException {
+    final java.sql.Date getDate(int column, Calendar cal) throws SqlException {
         switch (jdbcTypes_[column - 1]) {
         case java.sql.Types.DATE:
-            return getDATE(column);
+            return getDATE(column, cal);
         case java.sql.Types.TIMESTAMP:
-            return getDateFromTIMESTAMP(column);
+            return getDateFromTIMESTAMP(column, cal);
         case java.sql.Types.CHAR:
-            return agent_.crossConverters_.getDateFromString(getCHAR(column));
+            return agent_.crossConverters_.
+                    getDateFromString(getCHAR(column), cal);
         case java.sql.Types.VARCHAR:
         case java.sql.Types.LONGVARCHAR:
-            return agent_.crossConverters_.getDateFromString(getVARCHAR(column));
+            return agent_.crossConverters_.
+                    getDateFromString(getVARCHAR(column), cal);
         default:
             throw new ColumnTypeConversionException(agent_.logWriter_,
                 "java.sql.Types " + jdbcTypes_[column -1], "java.sql.Date");
         }
     }
 
-    final java.sql.Time getTime(int column) throws SqlException {
+    final java.sql.Time getTime(int column, Calendar cal) throws SqlException {
         switch (jdbcTypes_[column - 1]) {
         case java.sql.Types.TIME:
-            return getTIME(column);
+            return getTIME(column, cal);
         case java.sql.Types.TIMESTAMP:
-            return getTimeFromTIMESTAMP(column);
+            return getTimeFromTIMESTAMP(column, cal);
         case java.sql.Types.CHAR:
-            return agent_.crossConverters_.getTimeFromString(getCHAR(column));
+            return agent_.crossConverters_.
+                    getTimeFromString(getCHAR(column), cal);
         case java.sql.Types.VARCHAR:
         case java.sql.Types.LONGVARCHAR:
-            return agent_.crossConverters_.getTimeFromString(getVARCHAR(column));
+            return agent_.crossConverters_.
+                    getTimeFromString(getVARCHAR(column), cal);
         default:
             throw new ColumnTypeConversionException(agent_.logWriter_,
                 "java.sql.Types " + jdbcTypes_[column -1], "java.sql.Time");
         }
     }
 
-    final java.sql.Timestamp getTimestamp(int column) throws SqlException {
+    final java.sql.Timestamp getTimestamp(int column, Calendar cal)
+            throws SqlException {
         switch (jdbcTypes_[column - 1]) {
         case java.sql.Types.TIMESTAMP:
-            return getTIMESTAMP(column);
+            return getTIMESTAMP(column, cal);
         case java.sql.Types.DATE:
-            return getTimestampFromDATE(column);
+            return getTimestampFromDATE(column, cal);
         case java.sql.Types.TIME:
-            return getTimestampFromTIME(column);
+            return getTimestampFromTIME(column, cal);
         case java.sql.Types.CHAR:
-            return agent_.crossConverters_.getTimestampFromString(getCHAR(column));
+            return agent_.crossConverters_.
+                    getTimestampFromString(getCHAR(column), cal);
         case java.sql.Types.VARCHAR:
         case java.sql.Types.LONGVARCHAR:
-            return agent_.crossConverters_.getTimestampFromString(getVARCHAR(column));
+            return agent_.crossConverters_.
+                    getTimestampFromString(getVARCHAR(column), cal);
         default:
             throw new ColumnTypeConversionException(agent_.logWriter_,
                 "java.sql.Types " + jdbcTypes_[column -1], "java.sql.Timestamp");
@@ -1317,11 +1332,11 @@ public abstract class Cursor {
         case java.sql.Types.DECIMAL:
             return get_DECIMAL(column);
         case java.sql.Types.DATE:
-            return getDATE(column);
+            return getDATE(column, getRecyclableCalendar());
         case java.sql.Types.TIME:
-            return getTIME(column);
+            return getTIME(column, getRecyclableCalendar());
         case java.sql.Types.TIMESTAMP:
-            return getTIMESTAMP(column);
+            return getTIMESTAMP(column, getRecyclableCalendar());
         case java.sql.Types.CHAR:
             return getCHAR(column);
         case java.sql.Types.VARCHAR:

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java?rev=938547&r1=938546&r2=938547&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java Tue Apr 27 16:34:46
2010
@@ -24,8 +24,12 @@ package org.apache.derby.client.am;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Reader;
+import java.sql.Date;
 import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
 import java.util.Arrays;
+import java.util.Calendar;
 import org.apache.derby.client.am.SQLExceptionFactory;
 import org.apache.derby.shared.common.reference.SQLState;
 import org.apache.derby.shared.common.sanity.SanityManager;
@@ -861,7 +865,7 @@ public abstract class ResultSet implemen
     }
 
     // Live life on the edge and run unsynchronized
-    public java.sql.Date getDate(int column) throws SQLException {
+    public java.sql.Date getDate(int column, Calendar cal) throws SQLException {
 	    try
         {
             closeCloseFilterInputStream();
@@ -870,11 +874,21 @@ public abstract class ResultSet implemen
                 agent_.logWriter_.traceEntry(this, "getDate", column);
             }
             checkGetterPreconditions(column);
+
+            if (cal == null) {
+                throw new SqlException(agent_.logWriter_,
+                    new ClientMessageId(SQLState.CALENDAR_IS_NULL));
+            }
+
             java.sql.Date result = null;
             if (wasNonNullSensitiveUpdate(column)) {
                 result = (java.sql.Date) agent_.crossConverters_.setObject(java.sql.Types.DATE,
updatedColumns_[column - 1]);
+                // updateDate() doesn't take a calendar, so the retrieved
+                // value will be in the default calendar. Convert it to
+                // the requested calendar before returning it.
+                result = convertFromDefaultCalendar(result, cal);
             } else {
-                result = isNull(column) ? null : cursor_.getDate(column);
+                result = isNull(column) ? null : cursor_.getDate(column, cal);
             }
             if (agent_.loggingEnabled()) {
                 agent_.logWriter_.traceExit(this, "getDate", result);
@@ -889,57 +903,35 @@ public abstract class ResultSet implemen
     }
 
     // Live life on the edge and run unsynchronized
-    public java.sql.Date getDate(int column, java.util.Calendar calendar) throws SQLException
{
-        try
-        {
-            closeCloseFilterInputStream();
-
-            if (agent_.loggingEnabled()) {
-                agent_.logWriter_.traceEntry(this, "getDate", column, calendar);
-            }
-            java.sql.Date date = getDate(column);
-            if (calendar == null) {
-                throw new SqlException(agent_.logWriter_, 
-                    new ClientMessageId(SQLState.CALENDAR_IS_NULL));
-            }
-            if (date != null) {
-                java.util.Calendar targetCalendar = java.util.Calendar.getInstance(calendar.getTimeZone());
-                targetCalendar.clear();
-                targetCalendar.setTime(date);
-                java.util.Calendar defaultCalendar = java.util.Calendar.getInstance();
-                defaultCalendar.clear();
-                defaultCalendar.setTime(date);
-                long timeZoneOffset =
-                        targetCalendar.get(java.util.Calendar.ZONE_OFFSET) - defaultCalendar.get(java.util.Calendar.ZONE_OFFSET)
+
-                        targetCalendar.get(java.util.Calendar.DST_OFFSET) - defaultCalendar.get(java.util.Calendar.DST_OFFSET);
-                date.setTime(date.getTime() - timeZoneOffset);
-            }
-            if (agent_.loggingEnabled()) {
-                agent_.logWriter_.traceExit(this, "getDate", date);
-            }
-            return date;
-        }
-        catch ( SqlException se )
-        {
-            throw se.getSQLException();
-        }            
+    public java.sql.Date getDate(int column) throws SQLException {
+        return getDate(column, Calendar.getInstance());
     }
 
     // Live life on the edge and run unsynchronized
-    public java.sql.Time getTime(int column) throws SQLException {
+    public java.sql.Time getTime(int column, Calendar cal) throws SQLException {
         try
         {
             closeCloseFilterInputStream();
 
             if (agent_.loggingEnabled()) {
-                agent_.logWriter_.traceEntry(this, "getTime", column);
+                agent_.logWriter_.traceEntry(this, "getTime", column, cal);
             }
             checkGetterPreconditions(column);
+
+            if (cal == null) {
+                throw new SqlException(agent_.logWriter_,
+                    new ClientMessageId(SQLState.CALENDAR_IS_NULL));
+            }
+
             java.sql.Time result = null;
             if (wasNonNullSensitiveUpdate(column)) {
                 result = (java.sql.Time) agent_.crossConverters_.setObject(java.sql.Types.TIME,
updatedColumns_[column - 1]);
+                // updateTime() doesn't take a calendar, so the retrieved
+                // value will be in the default calendar. Convert it to
+                // the requested calendar before returning it.
+                result = convertFromDefaultCalendar(result, cal);
             } else {
-                result = isNull(column) ? null : cursor_.getTime(column);
+                result = isNull(column) ? null : cursor_.getTime(column, cal);
             }
             if (agent_.loggingEnabled()) {
                 agent_.logWriter_.traceExit(this, "getTime", result);
@@ -954,57 +946,37 @@ public abstract class ResultSet implemen
     }
 
     // Live life on the edge and run unsynchronized
-    public java.sql.Time getTime(int column, java.util.Calendar calendar) throws SQLException
{
-        try
-        {
-            closeCloseFilterInputStream();
-
-            if (agent_.loggingEnabled()) {
-                agent_.logWriter_.traceEntry(this, "getTime", column, calendar);
-            }
-            java.sql.Time time = getTime(column);
-            if (calendar == null) {
-                throw new SqlException(agent_.logWriter_,
-                    new ClientMessageId(SQLState.CALENDAR_IS_NULL));
-            }
-            if (time != null) {
-                java.util.Calendar targetCalendar = java.util.Calendar.getInstance(calendar.getTimeZone());
-                targetCalendar.clear();
-                targetCalendar.setTime(time);
-                java.util.Calendar defaultCalendar = java.util.Calendar.getInstance();
-                defaultCalendar.clear();
-                defaultCalendar.setTime(time);
-                long timeZoneOffset =
-                        targetCalendar.get(java.util.Calendar.ZONE_OFFSET) - defaultCalendar.get(java.util.Calendar.ZONE_OFFSET)
+
-                        targetCalendar.get(java.util.Calendar.DST_OFFSET) - defaultCalendar.get(java.util.Calendar.DST_OFFSET);
-                time.setTime(time.getTime() - timeZoneOffset);
-            }
-            if (agent_.loggingEnabled()) {
-                agent_.logWriter_.traceExit(this, "getTime", time);
-            }
-            return time;
-        }
-        catch ( SqlException se )
-        {
-            throw se.getSQLException();
-        }
+    public java.sql.Time getTime(int column) throws SQLException {
+        return getTime(column, Calendar.getInstance());
     }
 
     // Live life on the edge and run unsynchronized
-    public java.sql.Timestamp getTimestamp(int column) throws SQLException {
+    public java.sql.Timestamp getTimestamp(int column, Calendar calendar)
+            throws SQLException {
 	    try
         {
             closeCloseFilterInputStream();
 
             if (agent_.loggingEnabled()) {
-                agent_.logWriter_.traceEntry(this, "getTimestamp", column);
+                agent_.logWriter_.traceEntry(
+                        this, "getTimestamp", column, calendar);
             }
             checkGetterPreconditions(column);
+
+            if (calendar == null) {
+                throw new SqlException(agent_.logWriter_,
+                    new ClientMessageId(SQLState.CALENDAR_IS_NULL));
+            }
+
             java.sql.Timestamp result = null;
             if (wasNonNullSensitiveUpdate(column)) {
                 result = (java.sql.Timestamp) agent_.crossConverters_.setObject(java.sql.Types.TIMESTAMP,
updatedColumns_[column - 1]);
-            } else {
-                result = isNull(column) ? null : cursor_.getTimestamp(column);
+                // updateTimestamp() doesn't take a calendar, so the retrieved
+                // value will be in the default calendar. Convert it to
+                // the requested calendar before returning it.
+                result = convertFromDefaultCalendar(result, calendar);
+            } else if (!isNull(column)) {
+                result = cursor_.getTimestamp(column, calendar);
             }
             if (agent_.loggingEnabled()) {
                 agent_.logWriter_.traceExit(this, "getTimestamp", result);
@@ -1019,42 +991,56 @@ public abstract class ResultSet implemen
     }
 
     // Live life on the edge and run unsynchronized
-    public java.sql.Timestamp getTimestamp(int column, java.util.Calendar calendar) throws
SQLException {
-        try
-        {
-            closeCloseFilterInputStream();
+    public java.sql.Timestamp getTimestamp(int column) throws SQLException {
+        return getTimestamp(column, Calendar.getInstance());
+    }
 
-            if (agent_.loggingEnabled()) {
-                agent_.logWriter_.traceEntry(this, "getTimestamp", column, calendar);
-            }
-            java.sql.Timestamp timestamp = getTimestamp(column);
-            if (calendar == null) {
-                throw new SqlException(agent_.logWriter_, 
-                    new ClientMessageId(SQLState.CALENDAR_IS_NULL));
-            }
-            if (timestamp != null) {
-                int nano = timestamp.getNanos();
-                java.util.Calendar targetCalendar = java.util.Calendar.getInstance(calendar.getTimeZone());
-                targetCalendar.clear();
-                targetCalendar.setTime(timestamp);
-                java.util.Calendar defaultCalendar = java.util.Calendar.getInstance();
-                defaultCalendar.clear();
-                defaultCalendar.setTime(timestamp);
-                long timeZoneOffset =
-                        targetCalendar.get(java.util.Calendar.ZONE_OFFSET) - defaultCalendar.get(java.util.Calendar.ZONE_OFFSET)
+
-                        targetCalendar.get(java.util.Calendar.DST_OFFSET) - defaultCalendar.get(java.util.Calendar.DST_OFFSET);
-                timestamp.setTime(timestamp.getTime() - timeZoneOffset);
-                timestamp.setNanos(nano);
-            }
-            if (agent_.loggingEnabled()) {
-                agent_.logWriter_.traceExit(this, "getTimestamp", timestamp);
-            }
-            return timestamp;
-        }
-        catch ( SqlException se )
-        {
-            throw se.getSQLException();
-        }
+    /**
+     * Convert a date originally set using the default calendar to a value
+     * representing the same date in a different calendar.
+     *
+     * @param date the date to convert
+     * @param cal the calendar to convert it to
+     * @return a date object that represents the date in {@code cal}
+     */
+    private Date convertFromDefaultCalendar(Date date, Calendar cal) {
+        cal.clear();
+        cal.set(date.getYear() + 1900, date.getMonth(), date.getDate(),
+                0, 0, 0); // normalized time: 00:00:00
+        return new Date(cal.getTimeInMillis());
+    }
+
+    /**
+     * Convert a time originally set using the default calendar to a value
+     * representing the same time in a different calendar.
+     *
+     * @param time the time to convert
+     * @param cal the calendar to convert it to
+     * @return a time object that represents the time in {@code cal}
+     */
+    private Time convertFromDefaultCalendar(Time time, Calendar cal) {
+        cal.clear();
+        cal.set(1970, Calendar.JANUARY, 1, // normalized date: 1970-01-01
+                time.getHours(), time.getMinutes(), time.getSeconds());
+        return new Time(cal.getTimeInMillis());
+    }
+
+    /**
+     * Convert a timestamp originally set using the default calendar to a value
+     * representing the same timestamp in a different calendar.
+     *
+     * @param ts the timestamp to convert
+     * @param cal the calendar to convert it to
+     * @return a timestamp object that represents the timestamp in {@code cal}
+     */
+    private Timestamp convertFromDefaultCalendar(Timestamp ts, Calendar cal) {
+        cal.clear();
+        cal.set(ts.getYear() + 1900, ts.getMonth(), ts.getDate(),
+                ts.getHours(), ts.getMinutes(), ts.getSeconds());
+
+        Timestamp result = new Timestamp(cal.getTimeInMillis());
+        result.setNanos(ts.getNanos());
+        return result;
     }
 
     // Live life on the edge and run unsynchronized

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/_Suite.java?rev=938547&r1=938546&r2=938547&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/_Suite.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/_Suite.java
Tue Apr 27 16:34:46 2010
@@ -46,6 +46,7 @@ public class _Suite extends BaseTestCase
 		TestSuite suite = new TestSuite("jdbcapi");
 
 		suite.addTest(ConcurrencyTest.suite());
+        suite.addTest(DaylightSavingTest.suite());
 		suite.addTest(HoldabilityTest.suite());
 		suite.addTest(LobLengthTest.suite()); 
 		suite.addTest(ProcedureTest.suite());



Mime
View raw message