You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by rh...@apache.org on 2024/06/03 17:43:49 UTC

svn commit: r1918134 [1/2] - in /db/derby/code/branches/10.17: ./ java/org.apache.derby.client/org/apache/derby/client/am/ java/org.apache.derby.engine/org/apache/derby/iapi/types/ java/org.apache.derby.engine/org/apache/derby/impl/jdbc/ java/org.apach...

Author: rhillegas
Date: Mon Jun  3 17:43:48 2024
New Revision: 1918134

URL: http://svn.apache.org/viewvc?rev=1918134&view=rev
Log:
DERBY-6445: Port 1918123 from trunk to 10.17 branch.

Modified:
    db/derby/code/branches/10.17/   (props changed)
    db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/ClientCallableStatement.java
    db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/ClientPreparedStatement.java
    db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/ClientResultSet.java
    db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/CrossConverters.java
    db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/Cursor.java
    db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/DateTime.java
    db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/DateTimeValue.java
    db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/DataType.java
    db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/DataValueDescriptor.java
    db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLChar.java
    db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLClob.java
    db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLDate.java
    db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLTime.java
    db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLTimestamp.java
    db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/UserType.java
    db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/impl/jdbc/EmbedCallableStatement.java
    db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java
    db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/impl/jdbc/EmbedResultSet.java
    db/derby/code/branches/10.17/java/org.apache.derby.tests/org/apache/derbyTesting/functionTests/tests/jdbc4/CallableStatementTest.java
    db/derby/code/branches/10.17/java/org.apache.derby.tests/org/apache/derbyTesting/functionTests/tests/jdbc4/PreparedStatementTest42.java
    db/derby/code/branches/10.17/java/org.apache.derby.tests/org/apache/derbyTesting/functionTests/tests/jdbc4/Wrapper41Test.java

Propchange: db/derby/code/branches/10.17/
------------------------------------------------------------------------------
  Merged /db/derby/code/trunk:r1918123

Modified: db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/ClientCallableStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/ClientCallableStatement.java?rev=1918134&r1=1918133&r2=1918134&view=diff
==============================================================================
--- db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/ClientCallableStatement.java (original)
+++ db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/ClientCallableStatement.java Mon Jun  3 17:43:48 2024
@@ -41,6 +41,9 @@ import java.sql.SQLException;
 import java.sql.SQLXML;
 import java.sql.Time;
 import java.sql.Timestamp;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.util.Calendar;
 import java.util.Map;
 
@@ -500,6 +503,33 @@ public class ClientCallableStatement ext
         }
     }
 
+    private LocalDate getLocalDate(int parameterIndex) throws SQLException {
+        try
+        {
+            synchronized (connection_) {
+                if (agent_.loggingEnabled()) {
+                    agent_.logWriter_.traceEntry(
+                            this, "getLocalDate", parameterIndex);
+                }
+                super.checkForClosedStatement();
+                checkGetterPreconditions(parameterIndex);
+                
+                setWasNull(parameterIndex);
+                LocalDate result = wasNullX() ?
+                        null :
+                            singletonRowData_.getLocalDate(parameterIndex);
+                if (agent_.loggingEnabled()) {
+                    agent_.logWriter_.traceExit(this, "getLocalDate", result);
+                }
+                return result;
+            }
+        }
+        catch ( SqlException se )
+        {
+            throw se.getSQLException();
+        }
+    }
+
     public Date getDate(int parameterIndex) throws SQLException {
         return getDate(parameterIndex, Calendar.getInstance());
     }
@@ -540,6 +570,33 @@ public class ClientCallableStatement ext
         return getTime(parameterIndex, Calendar.getInstance());
     }
 
+    private LocalTime getLocalTime(int parameterIndex) throws SQLException {
+        try
+        {
+            synchronized (connection_) {
+                if (agent_.loggingEnabled()) {
+                    agent_.logWriter_.traceEntry(
+                            this, "getLocalTime", parameterIndex);
+                }
+                super.checkForClosedStatement();
+                checkGetterPreconditions(parameterIndex);
+
+                setWasNull(parameterIndex);
+                LocalTime result = wasNullX() ?
+                        null :
+                        singletonRowData_.getLocalTime(parameterIndex);
+                if (agent_.loggingEnabled()) {
+                    agent_.logWriter_.traceExit(this, "getLocalTime", result);
+                }
+                return result;
+            }
+        }
+        catch ( SqlException se )
+        {
+            throw se.getSQLException();
+        }
+    }
+
     public Timestamp getTimestamp(int parameterIndex, Calendar cal)
             throws SQLException {
         try
@@ -577,6 +634,34 @@ public class ClientCallableStatement ext
         return getTimestamp(parameterIndex, Calendar.getInstance());
     }
 
+    private LocalDateTime getLocalDateTime(int parameterIndex)
+            throws SQLException {
+        try
+        {
+            synchronized (connection_) {
+                if (agent_.loggingEnabled()) {
+                    agent_.logWriter_.traceEntry(
+                            this, "getLocalDateTime", parameterIndex);
+                }
+                super.checkForClosedStatement();
+                checkGetterPreconditions(parameterIndex);
+
+                setWasNull(parameterIndex);
+                LocalDateTime result = wasNullX() ?
+                        null :
+                        singletonRowData_.getLocalDateTime(parameterIndex);
+                if (agent_.loggingEnabled()) {
+                    agent_.logWriter_.traceExit(this, "getLocalDateTime", result);
+                }
+                return result;
+            }
+        }
+        catch ( SqlException se )
+        {
+            throw se.getSQLException();
+        }
+    }
+
     public String getString(int parameterIndex) throws SQLException {
         try
         {
@@ -1375,8 +1460,11 @@ public class ClientCallableStatement ext
         else if ( Float.class.equals( type ) ) { retval = Float.valueOf( getFloat( parameterIndex ) ); }
         else if ( Double.class.equals( type ) ) { retval = Double.valueOf( getDouble( parameterIndex ) ); }
         else if ( Date.class.equals( type ) ) { retval = getDate( parameterIndex ); }
+        else if ( LocalDate.class.equals( type ) ) { retval = getLocalDate( parameterIndex ); }
         else if ( Time.class.equals( type ) ) { retval = getTime( parameterIndex ); }
+        else if ( LocalTime.class.equals( type ) ) { retval = getLocalTime( parameterIndex ); }
         else if ( Timestamp.class.equals( type ) ) { retval = getTimestamp( parameterIndex ); }
+        else if ( LocalDateTime.class.equals( type ) ) { retval = getLocalDateTime( parameterIndex ); }
         else if ( Blob.class.equals( type ) ) { retval = getBlob( parameterIndex ); }
         else if ( Clob.class.equals( type ) ) { retval = getClob( parameterIndex ); }
         else if ( type.isArray() && type.getComponentType().equals( byte.class ) ) { retval = getBytes( parameterIndex ); }

Modified: db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/ClientPreparedStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/ClientPreparedStatement.java?rev=1918134&r1=1918133&r2=1918134&view=diff
==============================================================================
--- db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/ClientPreparedStatement.java (original)
+++ db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/ClientPreparedStatement.java Mon Jun  3 17:43:48 2024
@@ -44,6 +44,9 @@ import java.sql.SQLXML;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.sql.Types;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Calendar;
@@ -783,6 +786,41 @@ public class ClientPreparedStatement ext
         setDate(parameterIndex, x, Calendar.getInstance());
     }
 
+    private void setLocalDate(int parameterIndex, LocalDate x)
+            throws SQLException {
+        try
+        {
+            synchronized (connection_) {
+                
+                final int paramType = 
+                        getColumnMetaDataX().getColumnType(parameterIndex);
+                
+                if( ! PossibleTypes.POSSIBLE_TYPES_IN_SET_DATE.checkType(paramType) ){
+                    
+                    PossibleTypes.throw22005Exception(agent_.logWriter_ ,
+                            Types.DATE,
+                            paramType);
+                    
+                }
+                
+                checkForClosedStatement();
+                
+                parameterMetaData_.clientParamtertype_[parameterIndex - 1] =
+                        Types.DATE;
+                
+                if (x == null) {
+                    setNull(parameterIndex, Types.DATE);
+                    return;
+                }
+                setInput(parameterIndex, new DateTimeValue(x));
+            }
+        }
+        catch ( SqlException se )
+        {
+            throw se.getSQLException();
+        }
+    }
+
     public void setTime(int parameterIndex, Time x, Calendar calendar)
             throws SQLException {
         try
@@ -829,6 +867,39 @@ public class ClientPreparedStatement ext
         setTime(parameterIndex, x, Calendar.getInstance());
     }
 
+    private void setLocalTime(int parameterIndex, LocalTime x)
+            throws SQLException {
+        try
+        {
+            synchronized (connection_) {
+                
+                final int paramType = 
+                    getColumnMetaDataX().getColumnType(parameterIndex);
+
+                if( ! PossibleTypes.POSSIBLE_TYPES_IN_SET_TIME.checkType( paramType ) ){
+                    
+                    PossibleTypes.throw22005Exception( agent_.logWriter_,
+                                                       Types.TIME,
+                                                       paramType );
+                }
+
+                parameterMetaData_.clientParamtertype_[parameterIndex - 1] =
+                    Types.TIME;
+
+                if (x == null) {
+                    setNull(parameterIndex, Types.TIME);
+                    return;
+                }
+                setInput(parameterIndex, new DateTimeValue(x));
+
+            }
+        }
+        catch ( SqlException se )
+        {
+            throw se.getSQLException();
+        }
+    }
+
     public void setTimestamp(int parameterIndex, Timestamp x, Calendar calendar)
             throws SQLException {
         try
@@ -876,6 +947,39 @@ public class ClientPreparedStatement ext
         setTimestamp(parameterIndex, x, Calendar.getInstance());
     }
 
+    private void setLocalDateTime(int parameterIndex, LocalDateTime x)
+            throws SQLException {
+        try
+        {
+            synchronized (connection_) {
+                
+                final int paramType = 
+                    getColumnMetaDataX().getColumnType(parameterIndex);
+
+                if( ! PossibleTypes.POSSIBLE_TYPES_IN_SET_TIMESTAMP.checkType( paramType ) ) {
+                    
+                    PossibleTypes.throw22005Exception(agent_.logWriter_,
+                                                      Types.TIMESTAMP,
+                                                      paramType);
+                    
+                }
+
+                parameterMetaData_.clientParamtertype_[parameterIndex - 1] =
+                    Types.TIMESTAMP;
+
+                if (x == null) {
+                    setNull(parameterIndex, Types.TIMESTAMP);
+                    return;
+                }
+                setInput(parameterIndex, new DateTimeValue(x));
+            }
+        }
+        catch ( SqlException se )
+        {
+            throw se.getSQLException();
+        }
+    }
+
     public void setString(int parameterIndex, String x) throws SQLException {
         try
         {
@@ -1408,10 +1512,16 @@ public class ClientPreparedStatement ext
                     setBigDecimal(parameterIndex, (BigDecimal) x);
                 } else if (x instanceof Date) {
                     setDate(parameterIndex, (Date) x);
+                } else if (x instanceof LocalDate) {
+                    setLocalDate(parameterIndex, (LocalDate) x);
                 } else if (x instanceof Time) {
                     setTime(parameterIndex, (Time) x);
+                } else if (x instanceof LocalTime) {
+                    setLocalTime(parameterIndex, (LocalTime) x);
                 } else if (x instanceof Timestamp) {
                     setTimestamp(parameterIndex, (Timestamp) x);
+                } else if (x instanceof LocalDateTime) {
+                    setLocalDateTime(parameterIndex, (LocalDateTime) x);
                 } else if (x instanceof Blob) {
                     setBlob(parameterIndex, (Blob) x);
                 } else if (x instanceof Clob) {

Modified: db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/ClientResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/ClientResultSet.java?rev=1918134&r1=1918133&r2=1918134&view=diff
==============================================================================
--- db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/ClientResultSet.java (original)
+++ db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/ClientResultSet.java Mon Jun  3 17:43:48 2024
@@ -46,6 +46,9 @@ import java.sql.Statement;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.sql.Types;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Iterator;
@@ -919,6 +922,40 @@ public abstract class ClientResultSet im
     }
 
     // Live life on the edge and run unsynchronized
+    private LocalDate getLocalDate(int column) throws SQLException {
+        try
+        {
+            closeOpenStreams();
+
+            if (agent_.loggingEnabled()) {
+                agent_.logWriter_.traceEntry(this, "getLocalDate", column);
+            }
+            checkGetterPreconditions(column, "getObject");
+
+            LocalDate result = null;
+            if (wasNonNullSensitiveUpdate(column)) {
+                Date date = (Date)agent_.crossConverters_.setObject(
+                        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(date, Calendar.getInstance()).toLocalDate();
+            } else {
+                result = isNull(column) ? null : cursor_.getLocalDate(column);
+            }
+            if (agent_.loggingEnabled()) {
+                agent_.logWriter_.traceExit(this, "getLocalDate", result);
+            }
+            setWasNull(column);  // Placed close to the return to minimize risk of thread interference
+            return result;
+        }
+        catch ( SqlException se )
+        {
+            throw se.getSQLException();
+        }
+    }
+
+    // Live life on the edge and run unsynchronized
     public Time getTime(int column, Calendar cal) throws SQLException {
         try
         {
@@ -963,6 +1000,40 @@ public abstract class ClientResultSet im
     }
 
     // Live life on the edge and run unsynchronized
+    private LocalTime getLocalTime(int column) throws SQLException {
+        try
+        {
+            closeOpenStreams();
+
+            if (agent_.loggingEnabled()) {
+                agent_.logWriter_.traceEntry(this, "getLocalTime", column);
+            }
+            checkGetterPreconditions(column, "getObject");
+
+            LocalTime result = null;
+            if (wasNonNullSensitiveUpdate(column)) {
+                Time time = (Time)agent_.crossConverters_.setObject(
+                    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(time, Calendar.getInstance()).toLocalTime();
+            } else {
+                result = isNull(column) ? null : cursor_.getLocalTime(column);
+            }
+            if (agent_.loggingEnabled()) {
+                agent_.logWriter_.traceExit(this, "getLocalTime", result);
+            }
+            setWasNull(column);  // Placed close to the return to minimize risk of thread interference
+            return result;
+        }
+        catch ( SqlException se )
+        {
+            throw se.getSQLException();
+        }
+    }
+
+    // Live life on the edge and run unsynchronized
     public Timestamp getTimestamp(int column, Calendar calendar)
             throws SQLException {
         try
@@ -1008,6 +1079,42 @@ public abstract class ClientResultSet im
         return getTimestamp(column, Calendar.getInstance());
     }
 
+    // Live life on the edge and run unsynchronized
+    private LocalDateTime getLocalDateTime(int column)
+            throws SQLException {
+        try
+        {
+            closeOpenStreams();
+
+            if (agent_.loggingEnabled()) {
+                agent_.logWriter_.traceEntry(
+                        this, "getLocalDateTime", column);
+            }
+            checkGetterPreconditions(column, "getObject");
+
+            LocalDateTime result = null;
+            if (wasNonNullSensitiveUpdate(column)) {
+                Timestamp timestamp = (Timestamp)agent_.crossConverters_.setObject(
+                    Types.TIMESTAMP, updatedColumns_[column - 1]);
+                // 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(timestamp, Calendar.getInstance()).toLocalDateTime();
+            } else if (!isNull(column)) {
+                result = cursor_.getLocalDateTime(column);
+            }
+            if (agent_.loggingEnabled()) {
+                agent_.logWriter_.traceExit(this, "getLocalDateTime", result);
+            }
+            setWasNull(column);  // Placed close to the return to minimize risk of thread interference
+            return result;
+        }
+        catch ( SqlException se )
+        {
+            throw se.getSQLException();
+        }
+    }
+
     /**
      * Create a calendar with default locale and time zone.
      * @param date the initial time of the calendar
@@ -6510,8 +6617,11 @@ public abstract class ClientResultSet im
         else if ( Float.class.equals( type ) ) { retval = Float.valueOf( getFloat( columnIndex ) ); }
         else if ( Double.class.equals( type ) ) { retval = Double.valueOf( getDouble( columnIndex ) ); }
         else if ( Date.class.equals( type ) ) { retval = getDate( columnIndex ); }
+        else if ( LocalDate.class.equals( type ) ) { retval = getLocalDate( columnIndex ); }
         else if ( Time.class.equals( type ) ) { retval = getTime( columnIndex ); }
+        else if ( LocalTime.class.equals( type ) ) { retval = getLocalTime( columnIndex ); }
         else if ( Timestamp.class.equals( type ) ) { retval = getTimestamp( columnIndex ); }
+        else if ( LocalDateTime.class.equals( type ) ) { retval = getLocalDateTime( columnIndex ); }
 
         else if ( Blob.class.equals( type ) ) {
             retval = getBlob( columnIndex );

Modified: db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/CrossConverters.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/CrossConverters.java?rev=1918134&r1=1918133&r2=1918134&view=diff
==============================================================================
--- db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/CrossConverters.java (original)
+++ db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/CrossConverters.java Mon Jun  3 17:43:48 2024
@@ -37,6 +37,12 @@ import java.sql.Ref;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.sql.Types;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.temporal.ChronoField;
 import java.util.Calendar;
 import java.util.Locale;
 import org.apache.derby.shared.common.reference.SQLState;
@@ -65,6 +71,25 @@ final class CrossConverters {
      */
     public static final int UNKNOWN_LENGTH = Integer.MIN_VALUE;
 
+    // Formats and parses a LocalDateTime in way compatible to Timestamp
+    private static final DateTimeFormatter TIMESTAMP_FORMATTER = new DateTimeFormatterBuilder()
+        .appendValue(ChronoField.YEAR, 4)
+        .appendLiteral('-')
+        .appendValue(ChronoField.MONTH_OF_YEAR)
+        .appendLiteral('-')
+        .appendValue(ChronoField.DAY_OF_MONTH)
+        .appendLiteral(' ')
+        .appendValue(ChronoField.HOUR_OF_DAY)
+        .appendLiteral(':')
+        .appendValue(ChronoField.MINUTE_OF_HOUR)
+        .appendLiteral(':')
+        .appendValue(ChronoField.SECOND_OF_MINUTE)
+        .optionalStart()
+        .appendLiteral('.')
+        .appendFraction(ChronoField.NANO_OF_SECOND, 1, 9, false)
+        .optionalEnd()
+        .toFormatter();
+
     private final static BigDecimal bdMaxByteValue__ =
             BigDecimal.valueOf(Byte.MAX_VALUE);
     private final static BigDecimal bdMinByteValue__ =
@@ -585,6 +610,29 @@ final class CrossConverters {
         }
     }
 
+    // Convert from date source to target type
+    // In support of PS.setObject()
+    final Object setObject(int targetType, LocalDate source) throws SqlException {
+        switch (targetType) {
+
+        case Types.DATE:
+            return Date.valueOf(source);
+            
+        case Types.TIMESTAMP:
+            return Timestamp.valueOf(source.atStartOfDay());
+
+        case Types.CHAR:
+        case Types.VARCHAR:
+        case Types.LONGVARCHAR:
+            return String.valueOf(source);
+
+        default:
+            throw new SqlException(agent_.logWriter_, 
+                    new ClientMessageId (SQLState.LANG_DATA_TYPE_SET_MISMATCH),
+                    "java.time.LocalDate", ClientTypes.getTypeString(targetType));
+        }
+    }
+
     // Convert from time source to target type
     // In support of PS.setTime()
     final Object setObject(int targetType, Time source) throws SqlException {
@@ -605,6 +653,26 @@ final class CrossConverters {
         }
     }
 
+    // Convert from time source to target type
+    // In support of PS.setObject()
+    final Object setObject(int targetType, LocalTime source) throws SqlException {
+        switch (targetType) {
+
+        case Types.TIME:
+            return Time.valueOf(source);
+
+        case Types.CHAR:
+        case Types.VARCHAR:
+        case Types.LONGVARCHAR:
+            return String.valueOf(source);
+
+        default:
+            throw new SqlException(agent_.logWriter_, 
+                    new ClientMessageId (SQLState.LANG_DATA_TYPE_SET_MISMATCH),
+                    "java.time.LocalTime", ClientTypes.getTypeString(targetType));
+        }
+    }
+
     // Convert from date source to target type
     // In support of PS.setTimestamp()
     final Object setObject(int targetType, Timestamp source)
@@ -632,6 +700,33 @@ final class CrossConverters {
         }
     }
 
+    // Convert from date source to target type
+    // In support of PS.setObject()
+    final Object setObject(int targetType, LocalDateTime source)
+            throws SqlException {
+        switch (targetType) {
+
+        case Types.TIMESTAMP:
+            return Timestamp.valueOf(source);
+
+        case Types.TIME:
+            return Time.valueOf(source.toLocalTime());
+
+        case Types.DATE:
+            return Date.valueOf(source.toLocalDate());
+
+        case Types.CHAR:
+        case Types.VARCHAR:
+        case Types.LONGVARCHAR:
+            return source.format(TIMESTAMP_FORMATTER);
+
+        default:
+            throw new SqlException(agent_.logWriter_, 
+                    new ClientMessageId (SQLState.LANG_DATA_TYPE_SET_MISMATCH),
+                    "java.time.LocalDateTime", ClientTypes.getTypeString(targetType));
+        }
+    }
+
     // setString() against BINARY columns cannot be implemented consistently because w/out metadata, we'll send char encoding bytes.
     // So we refuse setString() requests altogether.
     // Convert from string source to target type.
@@ -957,10 +1052,16 @@ final class CrossConverters {
             return setObject(targetType, (BigDecimal) source);
         } else if (source instanceof Date) {
             return setObject(targetType, (Date) source);
+        } else if (source instanceof LocalDate) {
+            return setObject(targetType, (LocalDate) source);
         } else if (source instanceof Time) {
             return setObject(targetType, (Time) source);
+        } else if (source instanceof LocalTime) {
+            return setObject(targetType, (LocalTime) source);
         } else if (source instanceof Timestamp) {
             return setObject(targetType, (Timestamp) source);
+        } else if (source instanceof LocalDateTime) {
+            return setObject(targetType, (LocalDateTime) source);
         } else if (source instanceof String) {
             return setObject(targetType, (String) source);
         } else if (source instanceof byte[]) {
@@ -1339,6 +1440,16 @@ final class CrossConverters {
         }
     }
 
+    final LocalDate getLocalDateFromString(String source)
+            throws SqlException {
+        try {
+            return localDate_parse(source);
+        } catch (IllegalArgumentException e) { // subsumes NumberFormatException
+            throw new SqlException(agent_.logWriter_, 
+                    new ClientMessageId (SQLState.LANG_DATE_SYNTAX_EXCEPTION), e);
+        }
+    }
+
     //---------------------------- getTime*() methods ----------------------------
 
     final Time getTimeFromString(String source, Calendar cal)
@@ -1351,6 +1462,16 @@ final class CrossConverters {
         }
     }
 
+    final LocalTime getLocalTimeFromString(String source)
+            throws SqlException {
+        try {
+            return localTime_valueOf(source);
+        } catch (IllegalArgumentException e) { // subsumes NumberFormatException
+            throw new SqlException(agent_.logWriter_, 
+                    new ClientMessageId (SQLState.LANG_DATE_SYNTAX_EXCEPTION), e);
+        }
+    }
+
     //---------------------------- getTimestamp*() methods -----------------------
 
     final Timestamp getTimestampFromString(String source, Calendar cal)
@@ -1363,6 +1484,16 @@ final class CrossConverters {
         }
     }
 
+    final LocalDateTime getLocalDateTimeFromString(String source)
+            throws SqlException {
+        try {
+            return localDateTime_parse(source);
+        } catch (IllegalArgumentException e) { // subsumes NumberFormatException
+            throw new SqlException(agent_.logWriter_, 
+                    new ClientMessageId (SQLState.LANG_DATE_SYNTAX_EXCEPTION), e);
+        }
+    }
+
     /**
      * Convert a string to a date in the specified calendar. Accept the same
      * format as {@code Date.valueOf()}.
@@ -1447,6 +1578,16 @@ final class CrossConverters {
         return result;
     }
 
+    private static LocalDate localDate_parse(String s) {
+        String formatError = "JDBC Date format must be yyyy-mm-dd";
+        if (s == null) {
+            throw new IllegalArgumentException(formatError);
+        }
+        s = s.trim();
+
+        return LocalDate.parse(s);
+    }
+
     /**
      * Convert a string to a time in the specified calendar. Accept the same
      * format as {@code java.sql.Time.valueOf()}.
@@ -1501,6 +1642,20 @@ final class CrossConverters {
         cal.set(Calendar.SECOND, second);
     }
 
+    private static LocalTime localTime_valueOf(String s) {
+        if (s == null) {
+            throw new IllegalArgumentException();
+        }
+        s = s.trim();
+        // Expect string on format HH:MM:SS
+        if (s.length() != 8 ||
+                s.charAt(2) != ':' || s.charAt(5) != ':') {
+            throw new IllegalArgumentException();
+        }
+
+        return LocalTime.parse(s);
+    }
+
     /**
      * Convert a string to a timestamp in the specified calendar. Accept the
      * same format as {@code java.sql.Timestamp.valueOf()}.
@@ -1721,4 +1876,14 @@ final class CrossConverters {
             }
         }
     }
+
+    private static LocalDateTime localDateTime_parse(String s) {
+        if (s == null) {
+            throw new IllegalArgumentException();
+        }
+
+        s = s.trim();
+
+        return LocalDateTime.parse(s, TIMESTAMP_FORMATTER);
+    }
 }

Modified: db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/Cursor.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/Cursor.java?rev=1918134&r1=1918133&r2=1918134&view=diff
==============================================================================
--- db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/Cursor.java (original)
+++ db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/Cursor.java Mon Jun  3 17:43:48 2024
@@ -42,6 +42,9 @@ import java.sql.Ref;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.sql.Types;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.GregorianCalendar;
@@ -485,6 +488,12 @@ public abstract class Cursor {
             charset_[column - 1]);
     }
 
+    private LocalDate getLocalDateFromDATE(int column) throws SqlException {
+        return DateTime.dateBytesToLocalDate(dataBuffer_,
+                columnDataPosition_[column - 1],
+                charset_[column - 1]);
+    }
+
     // Build a JDBC Time object from the DERBY ISO TIME field.
     private Time getTIME(int column, Calendar cal) throws SqlException {
         return DateTime.timeBytesToTime(dataBuffer_,
@@ -493,6 +502,12 @@ public abstract class Cursor {
                 charset_[column - 1]);
     }
 
+    private LocalTime getLocalTimeFromTIME(int column) throws SqlException {
+        return DateTime.timeBytesToLocalTime(dataBuffer_,
+                columnDataPosition_[column - 1],
+                charset_[column - 1]);
+    }
+
     // Build a JDBC Timestamp object from the DERBY ISO TIMESTAMP field.
     private final Timestamp getTIMESTAMP(int column, Calendar cal)
             throws SqlException {
@@ -504,6 +519,15 @@ public abstract class Cursor {
             agent_.connection_.serverSupportsTimestampNanoseconds());
     }
 
+    private final LocalDateTime getLocalDateTimeFromTIMESTAMP(int column)
+            throws SqlException {
+        return DateTime.timestampBytesToLocalDateTime(
+                dataBuffer_,
+                columnDataPosition_[column - 1],
+                charset_[column - 1],
+                agent_.connection_.serverSupportsTimestampNanoseconds());
+    }
+
     // Build a JDBC Timestamp object from the DERBY ISO DATE field.
     private final Timestamp getTimestampFromDATE(
             int column, Calendar cal) throws SqlException {
@@ -922,6 +946,24 @@ public abstract class Cursor {
         }
     }
 
+    final LocalDate getLocalDate(int column) throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case Types.DATE:
+            return getLocalDateFromDATE(column);
+        case Types.TIMESTAMP:
+            return getLocalDateTimeFromTIMESTAMP(column).toLocalDate();
+        case Types.CHAR:
+            return agent_.crossConverters_.
+                    getLocalDateFromString(getCHAR(column));
+        case Types.VARCHAR:
+        case Types.LONGVARCHAR:
+            return agent_.crossConverters_.
+                    getLocalDateFromString(getVARCHAR(column));
+        default:
+            throw coercionError( "java.time.LocalDate", column );
+        }
+    }
+
     final Time getTime(int column, Calendar cal) throws SqlException {
         switch (jdbcTypes_[column - 1]) {
         case Types.TIME:
@@ -940,6 +982,24 @@ public abstract class Cursor {
         }
     }
 
+    final LocalTime getLocalTime(int column) throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case Types.TIME:
+            return getLocalTimeFromTIME(column);
+        case Types.TIMESTAMP:
+            return getLocalDateTimeFromTIMESTAMP(column).toLocalTime();
+        case Types.CHAR:
+            return agent_.crossConverters_.
+                    getLocalTimeFromString(getCHAR(column));
+        case Types.VARCHAR:
+        case Types.LONGVARCHAR:
+            return agent_.crossConverters_.
+                    getLocalTimeFromString(getVARCHAR(column));
+        default:
+            throw coercionError( "java.time.LocalTime", column );
+        }
+    }
+
     final Timestamp getTimestamp(int column, Calendar cal)
             throws SqlException {
         switch (jdbcTypes_[column - 1]) {
@@ -961,6 +1021,27 @@ public abstract class Cursor {
         }
     }
 
+    final LocalDateTime getLocalDateTime(int column)
+            throws SqlException {
+        switch (jdbcTypes_[column - 1]) {
+        case Types.TIMESTAMP:
+            return getLocalDateTimeFromTIMESTAMP(column);
+        case Types.DATE:
+            return getLocalDateFromDATE(column).atStartOfDay();
+        case Types.TIME:
+            return getLocalTimeFromTIME(column).atDate(DateTimeValue.TIME_EPOCH);
+        case Types.CHAR:
+            return agent_.crossConverters_.
+                    getLocalDateTimeFromString(getCHAR(column));
+        case Types.VARCHAR:
+        case Types.LONGVARCHAR:
+            return agent_.crossConverters_.
+                    getLocalDateTimeFromString(getVARCHAR(column));
+        default:
+            throw coercionError( "java.time.LocalDateTime", column );
+        }
+    }
+
     final String getString(int column) throws SqlException {
         try {
             String tempString;

Modified: db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/DateTime.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/DateTime.java?rev=1918134&r1=1918133&r2=1918134&view=diff
==============================================================================
--- db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/DateTime.java (original)
+++ db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/DateTime.java Mon Jun  3 17:43:48 2024
@@ -27,6 +27,9 @@ import java.nio.charset.Charset;
 import java.sql.Date;
 import java.sql.Time;
 import java.sql.Timestamp;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.util.Calendar;
 import java.util.GregorianCalendar;
 import org.apache.derby.client.net.Typdef;
@@ -110,6 +113,44 @@ public class DateTime {
         return new Date(cal.getTimeInMillis());
     }
 
+    /**
+     * Expected character representation is DERBY string representation of a date, 
+     * which is in JIS format: <code> yyyy-mm-dd </code>
+     * 
+     * @param buffer    
+     * @param offset    
+     * @param encoding            encoding of buffer data
+     * @return  LocalDate translated from  buffer with specified encoding
+     */
+    static final LocalDate dateBytesToLocalDate(byte[] buffer,
+            int offset,
+            Charset encoding) {
+
+        int year, month, day;
+
+        String date = new String(buffer, offset, 
+                DateTime.dateRepresentationLength,encoding);
+        int yearIndx, monthIndx, dayIndx;
+        if (date.charAt(4) == '-') {
+            // JIS format: yyyy-mm-dd.
+            yearIndx = 0;
+            monthIndx = 5;
+            dayIndx = 8;
+        } else {
+            throw new IllegalArgumentException(
+                    SqlException.getMessageUtil().getTextMessage(
+                            SQLState.LANG_FORMAT_EXCEPTION));
+        }
+
+        year = Integer.parseInt(date, yearIndx, yearIndx + 4, 10);
+
+        month = Integer.parseInt(date, monthIndx, monthIndx + 2, 10);
+
+        day = Integer.parseInt(date, dayIndx, dayIndx + 2, 10);
+
+        return LocalDate.of(year, month, day);
+    }
+
     
     /**
      * Expected character representation is DERBY string representation of time,
@@ -150,6 +191,33 @@ public class DateTime {
     }
 
     /**
+     * Expected character representation is DERBY string representation of time,
+     * which is in the format: <code> hh.mm.ss </code>
+     * @param buffer
+     * @param offset
+     * @param encoding           encoding of buffer
+     * @return  LocalTime translated from buffer with specified encoding
+     */
+    static final LocalTime timeBytesToLocalTime(byte[] buffer,
+            int offset,
+            Charset encoding)
+    {
+        int hour, minute, second;
+        
+        String time = new String(buffer, offset, 
+                DateTime.timeRepresentationLength, encoding);
+        
+        // compute hour.
+        hour = Integer.parseInt(time, 0, 2, 10);
+        // compute minute.
+        minute = Integer.parseInt(time, 3, 5, 10);
+        // compute second.
+        second = Integer.parseInt(time, 6, 8, 10);
+        
+        return LocalTime.of(hour, minute, second);
+    }
+
+    /**
      * See getTimestampLength() for an explanation of how timestamps are formatted.
      * 
      * @param buffer
@@ -179,6 +247,25 @@ public class DateTime {
     }
 
     /**
+     * See getTimestampLength() for an explanation of how timestamps are formatted.
+     * 
+     * @param buffer
+     * @param offset
+     * @param encoding                encoding of buffer
+     * @param supportsTimestampNanoseconds true if the server supports nanoseconds in timestamps
+     * @return LocalDateTime translated from buffer with specified encoding
+     */
+    static final LocalDateTime timestampBytesToLocalDateTime(
+            byte[] buffer, int offset,
+            Charset encoding, boolean supportsTimestampNanoseconds)
+    {
+        String timestamp = new String
+                ( buffer, offset, getTimestampLength( supportsTimestampNanoseconds ), encoding );
+        
+        return parseLocalDateTimeString(timestamp, supportsTimestampNanoseconds);
+    }
+
+    /**
      * Parse a String of the form <code>yyyy-mm-dd-hh.mm.ss.ffffff[fff]</code>
      * and store the various fields into the received Calendar object.
      *
@@ -246,6 +333,45 @@ public class DateTime {
         return nanos;
     }
 
+    /**
+     * Parse a String of the form <code>yyyy-mm-dd-hh.mm.ss.ffffff[fff]</code>
+     * and store the various fields into the received Calendar object.
+     *
+     * @param timestamp Timestamp value to parse, as a String.
+     * @param supportsTimestampNanoseconds true if the server supports nanoseconds in timestamps
+     *
+     * @return The nanoseconds field as parsed from the timestamp string.
+     *  This cannot be set in the Calendar object but we still want to
+     *  preserve the value, in case the caller needs it (for example, to
+     *  create a java.sql.Timestamp with nanosecond precision).
+     */
+    private static LocalDateTime parseLocalDateTimeString(String timestamp,
+            boolean supportsTimestampNanoseconds )
+    {
+        int year, month, day, hour, minute, second, nanos;
+
+        year = Integer.parseInt(timestamp, 0, 4, 10);
+
+        month = Integer.parseInt(timestamp, 5, 7, 10);
+
+        day = Integer.parseInt(timestamp, 8, 10, 10);
+
+        hour = Integer.parseInt(timestamp, 11, 13, 10);
+
+        minute = Integer.parseInt(timestamp, 14, 16, 10);
+
+        second = Integer.parseInt(timestamp, 17, 19, 10);
+
+        nanos = 1000 * Integer.parseInt(timestamp, 20, 26, 10);
+
+        if ( supportsTimestampNanoseconds )
+        {
+            nanos += Integer.parseInt(timestamp, 26, 29, 10);
+        }
+
+        return LocalDateTime.of(year, month, day, hour, minute, second, nanos);
+    }
+
     // ********************************************************
     // ********** Input converters (class -> byte[]) **********
     // ********************************************************

Modified: db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/DateTimeValue.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/DateTimeValue.java?rev=1918134&r1=1918133&r2=1918134&view=diff
==============================================================================
--- db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/DateTimeValue.java (original)
+++ db/derby/code/branches/10.17/java/org.apache.derby.client/org/apache/derby/client/am/DateTimeValue.java Mon Jun  3 17:43:48 2024
@@ -22,6 +22,9 @@ package org.apache.derby.client.am;
 import java.sql.Date;
 import java.sql.Time;
 import java.sql.Timestamp;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.util.Calendar;
 
 /**
@@ -36,6 +39,7 @@ import java.util.Calendar;
  * without being used together with a {@code java.util.Calendar} object.
  */
 public class DateTimeValue {
+    public static final LocalDate TIME_EPOCH = LocalDate.of(1970, 1, 1);
     private final int year;
     private final int month;
     private final int day;
@@ -103,6 +107,16 @@ public class DateTimeValue {
     }
 
     /**
+     * Create an instance from a {@code java.time.LocalDate} using the default
+     * calendar.
+     *
+     * @param localDate The wrapped date
+     */
+    public DateTimeValue(LocalDate localDate) {
+        this(localDate.atStartOfDay());
+    }
+
+    /**
      * Create an instance from a {@code java.sql.Time} using the default
      * calendar.
      *
@@ -113,6 +127,15 @@ public class DateTimeValue {
     }
 
     /**
+     * Create an instance from a {@code java.time.LocalTime}.
+     *
+     * @param localTime The wrapped time value
+     */
+    public DateTimeValue(LocalTime localTime) {
+        this(localTime.atDate(TIME_EPOCH));
+    }
+
+    /**
      * Create an instance from a {@code java.sql.Timestamp} using the default
      * calendar.
      *
@@ -123,6 +146,21 @@ public class DateTimeValue {
     }
 
     /**
+     * Create an instance from a {@code java.time.LocalDateTime}.
+     *
+     * @param ldt The wrapped local date time value
+     */
+    public DateTimeValue(LocalDateTime ldt) {
+        year = ldt.getYear();
+        month = ldt.getMonthValue() - 1;
+        day = ldt.getDayOfMonth();
+        hours = ldt.getHour();
+        minutes = ldt.getMinute();
+        seconds = ldt.getSecond();
+        nanos = ldt.getNano();
+    }
+
+    /**
      * Set the time of a calendar.
      *
      * @param cal the calendar

Modified: db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/DataType.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/DataType.java?rev=1918134&r1=1918133&r2=1918134&view=diff
==============================================================================
--- db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/DataType.java (original)
+++ db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/DataType.java Mon Jun  3 17:43:48 2024
@@ -34,6 +34,9 @@ import java.sql.Clob;
 import java.sql.Date;
 import java.sql.Time;
 import java.sql.Timestamp;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.sql.PreparedStatement;
 import java.sql.SQLException;
 import java.sql.ResultSet;
@@ -188,6 +191,18 @@ public abstract class DataType
 	}
 
 	/**
+     * Gets the value in the data value descriptor as a java.time.LocalDate.
+     * Throws an exception if the data value is not a Date.
+     * @return  The data value as a java.time.LocalDate.
+     *
+     * @exception StandardException   Thrown on error
+     */
+	public LocalDate	getLocalDate() throws StandardException
+	{
+	    throw dataTypeConversion("java.time.LocalDate");
+	}
+
+	/**
 	 * Gets the value in the data value descriptor as a java.sql.Time.
 	 * Throws an exception if the data value is not receivable as a Time.
      *	@param cal calendar for object creation
@@ -201,6 +216,18 @@ public abstract class DataType
 	}
 
 	/**
+     * Gets the value in the data value descriptor as a java.time.LocalDateTime.
+     * Throws an exception if the data value is not a Timestamp.
+     * @return  The data value as a java.time.LocalDateTime.
+     *
+     * @exception StandardException   Thrown on error
+     */
+	public LocalTime	getLocalTime() throws StandardException
+	{
+	    throw dataTypeConversion("java.time.LocalTime");
+	}
+
+	/**
 	 * Gets the value in the data value descriptor as a java.sql.Timestamp.
 	 * Throws an exception if the data value is not receivable as a Timestamp.
      *	@param cal calendar for object creation
@@ -214,6 +241,18 @@ public abstract class DataType
 	}
 
 	/**
+     * Gets the value in the data value descriptor as a java.time.LocalDateTime.
+     * Throws an exception if the data value is not a Timestamp.
+     * @return  The data value as a java.time.LocalDateTime.
+     *
+     * @exception StandardException   Thrown on error
+     */
+	public LocalDateTime	getLocalDateTime() throws StandardException
+	{
+	    throw dataTypeConversion("java.time.LocalDateTime");
+	}
+
+	/**
 	 * Gets the value in the data stream descriptor as an InputStream.
 	 * Throws an exception if the data value is not receivable as a stream.
 	 *
@@ -335,6 +374,17 @@ public abstract class DataType
 	 * Set the value of this DataValueDescriptor.
 	 * At DataType level just throws an error lower classes will override
 	 *
+	 * @param theValue	The LocalTime value to set this DataValueDescriptor to
+	 */
+	public void setValue(LocalTime theValue) throws StandardException
+	{
+	    throwLangSetMismatch("java.time.LocalTime");
+	}
+	
+	/**
+	 * Set the value of this DataValueDescriptor.
+	 * At DataType level just throws an error lower classes will override
+	 *
 	 * @param theValue	The Timestamp value to set this DataValueDescriptor to
 	 */
 	public void setValue(Timestamp theValue) throws StandardException
@@ -356,6 +406,16 @@ public abstract class DataType
 	
 	/**
 	 * Set the value of this DataValueDescriptor.
+     *
+     * @param theValue  The LocalDateTime value to set this DataValueDescriptor to
+     */
+	public void setValue(LocalDateTime theValue) throws StandardException
+	{
+	    throwLangSetMismatch("java.sql.Timestamp");
+	}
+	
+	/**
+	 * Set the value of this DataValueDescriptor.
 	 * At DataType level just throws an error lower classes will override
 	 *
 	 * @param theValue	The Date value to set this DataValueDescriptor to
@@ -378,6 +438,17 @@ public abstract class DataType
 	}
 
 	/**
+	 * Set the value of this DataValueDescriptor.
+     *
+     * @param theValue  The LocalDate value to set this DataValueDescriptor to
+     *
+     */
+	public void setValue(LocalDate theValue) throws StandardException
+	{
+	    throwLangSetMismatch("java.time.LocalDate");
+	}
+
+	/**
 	 * Set the value of this DataValueDescriptor.
 	 * At DataType level just throws an error lower classes will override
 	 *

Modified: db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/DataValueDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/DataValueDescriptor.java?rev=1918134&r1=1918133&r2=1918134&view=diff
==============================================================================
--- db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/DataValueDescriptor.java (original)
+++ db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/DataValueDescriptor.java Mon Jun  3 17:43:48 2024
@@ -36,6 +36,9 @@ import java.sql.ResultSet;
 import java.sql.PreparedStatement;
 import java.sql.Time;
 import java.sql.Timestamp;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.sql.SQLException;
 import java.util.Calendar;
 
@@ -241,6 +244,15 @@ public interface DataValueDescriptor ext
 	Date getDate(java.util.Calendar cal) throws StandardException;
 
 	/**
+	 * Gets the value in the data value descriptor as a java.time.LocalDate.
+	 * Throws an exception if the data value is not a Date.
+	 * @return	The data value as a java.time.LocalDate.
+	 *
+	 * @exception StandardException   Thrown on error
+	 */
+	LocalDate getLocalDate() throws StandardException;
+
+	/**
 	 * Gets the value in the data value descriptor as a java.sql.Time.
 	 * Throws an exception if the data value is not a Time.
      *	@param cal calendar for object creation
@@ -252,6 +264,16 @@ public interface DataValueDescriptor ext
 	Time	getTime(java.util.Calendar cal) throws StandardException;
 
 	/**
+	 * Gets the value in the data value descriptor as a java.time.LocalTime.
+	 * Throws an exception if the data value is not a Time.
+	 *
+	 * @return	The data value as a java.time.LocalTime.
+	 *
+	 * @exception StandardException   Thrown on error
+	 */
+	LocalTime	getLocalTime() throws StandardException;
+
+	/**
 	 * Gets the value in the data value descriptor as a java.sql.Timestamp.
 	 * Throws an exception if the data value is not a Timestamp.
      *	@param cal calendar for object creation
@@ -262,6 +284,15 @@ public interface DataValueDescriptor ext
 	Timestamp	getTimestamp(java.util.Calendar cal) throws StandardException;
 
 	/**
+	 * Gets the value in the data value descriptor as a java.time.LocalDateTime.
+	 * Throws an exception if the data value is not a Timestamp.
+	 * @return	The data value as a java.time.LocalDateTime.
+	 *
+	 * @exception StandardException   Thrown on error
+	 */
+	LocalDateTime	getLocalDateTime() throws StandardException;
+
+	/**
 	 * Gets the value in the data value descriptor as a Java Object.
 	 * The type of the Object will be the Java object type corresponding
 	 * to the data value's SQL type. JDBC defines a mapping between Java
@@ -538,6 +569,14 @@ public interface DataValueDescriptor ext
 	/**
 	 * Set the value of this DataValueDescriptor.
 	 *
+	 * @param theValue	The LocalTime value to set this DataValueDescriptor to
+	 *
+	 */
+	public void setValue(LocalTime theValue) throws StandardException;
+
+	/**
+	 * Set the value of this DataValueDescriptor.
+	 *
 	 * @param theValue	The Timestamp value to set this DataValueDescriptor to
 	 *
 	 */
@@ -555,6 +594,13 @@ public interface DataValueDescriptor ext
 	/**
 	 * Set the value of this DataValueDescriptor.
 	 *
+	 * @param theValue	The LocalDateTime value to set this DataValueDescriptor to
+	 */
+	public void setValue(LocalDateTime theValue) throws StandardException;
+
+	/**
+	 * Set the value of this DataValueDescriptor.
+	 *
 	 * @param theValue	The Date value to set this DataValueDescriptor to
 	 *
 	 */
@@ -570,6 +616,14 @@ public interface DataValueDescriptor ext
 	public void setValue(Date theValue, Calendar cal) throws StandardException;
 
 	/**
+	 * Set the value of this DataValueDescriptor.
+	 *
+	 * @param theValue	The LocalDate value to set this DataValueDescriptor to
+	 *
+	 */
+	public void setValue(LocalDate theValue) throws StandardException;
+
+	/**
 	 * Set the value of this DataValueDescriptor from another.
 	 *
 	 * @param theValue	The Date value to set this DataValueDescriptor to

Modified: db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLChar.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLChar.java?rev=1918134&r1=1918133&r2=1918134&view=diff
==============================================================================
--- db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLChar.java (original)
+++ db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLChar.java Mon Jun  3 17:43:48 2024
@@ -65,6 +65,9 @@ import java.sql.SQLException;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.text.RuleBasedCollator;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.text.CollationKey;
 import java.util.Arrays;
 import java.util.Locale;
@@ -515,6 +518,24 @@ public class SQLChar
     }
 
     /**
+     * Get date from a SQLChar.
+     *
+     * @see DataValueDescriptor#getDate
+     *
+     * @exception StandardException thrown on failure to convert
+     **/
+    public LocalDate getLocalDate() 
+            throws StandardException
+    {
+        String str = getString();
+        if( str == null)
+            return null;
+        SQLDate internalDate = new SQLDate(str, false, getLocaleFinder());
+
+        return internalDate.getLocalDate();
+    }
+
+    /**
      * Static function to Get date from a string.
      *
      * @see DataValueDescriptor#getDate
@@ -566,6 +587,15 @@ public class SQLChar
         return internalTime.getTime( cal);
     }
 
+    public LocalTime getLocalTime() throws StandardException
+    {
+        String str = getString();
+        if( str == null)
+            return null;
+        SQLTime internalTime = new SQLTime( str, false, getLocaleFinder());
+        return internalTime.getLocalTime();
+    }
+
     /**
      * Get Timestamp from a SQLChar.
      *
@@ -600,6 +630,17 @@ public class SQLChar
         return internalTimestamp.getTimestamp( cal);
     }
 
+    public LocalDateTime getLocalDateTime() throws StandardException
+    {
+        String str = getString();
+        if( str == null)
+            return null;
+
+        SQLTimestamp internalTimestamp = 
+            new SQLTimestamp( str, false, getLocaleFinder());
+        return internalTimestamp.getLocalDateTime();
+    }
+
     /**************************************************************************
      * Public Methods of StreamStorable interface:
      **************************************************************************
@@ -1607,6 +1648,19 @@ readingLoop:
     }
 
     /** @exception StandardException        Thrown on error */
+    public void setValue(LocalDate theValue) throws StandardException
+    {
+        String strValue = null;
+        if( theValue != null)
+        {
+            StringBuffer sb = new StringBuffer();
+            formatLocalDate( theValue, sb);
+            strValue= sb.toString();
+        }
+        setValue( strValue);
+    }
+
+    /** @exception StandardException        Thrown on error */
     public void setValue(Time theValue, Calendar cal) throws StandardException
     {
         String strValue = null;
@@ -1626,6 +1680,19 @@ readingLoop:
     }
 
     /** @exception StandardException        Thrown on error */
+    public void setValue(LocalTime theValue) throws StandardException
+    {
+        String strValue = null;
+        if( theValue != null)
+        {
+            StringBuffer sb = new StringBuffer();
+            formatLocalTime( theValue, sb);
+            strValue= sb.toString();
+        }
+        setValue( strValue);
+    }
+
+    /** @exception StandardException        Thrown on error */
     public void setValue(
     Timestamp   theValue, 
     Calendar    cal) 
@@ -1680,6 +1747,54 @@ readingLoop:
         setValue( strValue);
     }
 
+    /** @exception StandardException        Thrown on error */
+    public void setValue(
+    LocalDateTime   theValue) 
+        throws StandardException
+    {
+        String strValue = null;
+        if( theValue != null)
+        {
+            StringBuffer sb = new StringBuffer();
+            formatLocalDate( theValue.toLocalDate(), sb);
+            sb.append( ' ');
+            formatLocalTime( theValue.toLocalTime(), sb);
+            sb.append('.');
+            
+            int nanos = theValue.getNano();
+            
+            if (nanos == 0)
+            {
+                // Add a single zero after the decimal point to match
+                // the format from Timestamp.toString().
+                sb.append('0');
+            }
+            else if (nanos > 0)
+            {
+                String nanoString = Integer.toString(nanos);
+                int len = nanoString.length();
+                
+                // Add leading zeros if nanoString is shorter than
+                // MAX_FRACTION_DIGITS.
+                for (int i = len;
+                        i < SQLTimestamp.MAX_FRACTION_DIGITS; i++)
+                {
+                    sb.append('0');
+                }
+                
+                // Remove trailing zeros to match the format from
+                // Timestamp.toString().
+                while (nanoString.charAt(len - 1) == '0') {
+                    len--;
+                }
+                
+                sb.append(nanoString.substring(0, len));
+            strValue= sb.toString();
+            }
+        }
+        setValue( strValue);
+    }
+
     private void formatJDBCDate( Calendar cal, StringBuffer sb)
     {
         SQLDate.dateToString( cal.get( Calendar.YEAR),
@@ -1688,6 +1803,14 @@ readingLoop:
                               sb);
     }
 
+    private void formatLocalDate( LocalDate localDate, StringBuffer sb)
+    {
+        SQLDate.dateToString( localDate.getYear(),
+                localDate.getMonthValue(),
+                localDate.getDayOfMonth(),
+                sb);
+    }
+
     private void formatJDBCTime( Calendar cal, StringBuffer sb)
     {
         SQLTime.timeToString(
@@ -1697,6 +1820,15 @@ readingLoop:
             sb);
     }
 
+    private void formatLocalTime( LocalTime localTime, StringBuffer sb)
+    {
+        SQLTime.timeToString(
+                localTime.getHour(),
+                localTime.getMinute(), 
+                localTime.getSecond(), 
+                sb);
+    }
+
     /**
      * Set the value from the stream which is in the on-disk format.
      * @param theStream On disk format of the stream

Modified: db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLClob.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLClob.java?rev=1918134&r1=1918133&r2=1918134&view=diff
==============================================================================
--- db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLClob.java (original)
+++ db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLClob.java Mon Jun  3 17:43:48 2024
@@ -48,6 +48,9 @@ import java.sql.SQLException;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.text.RuleBasedCollator;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.util.Calendar;
 
 
@@ -339,6 +342,11 @@ public class SQLClob
 		throw dataTypeConversion("java.sql.Date");
 	}
 
+	public LocalDate	getLocalDate() throws StandardException
+	{
+	    throw dataTypeConversion("java.time.LocalDate");
+	}
+
     /**
      * @exception StandardException     Thrown on error
      */
@@ -463,11 +471,21 @@ public class SQLClob
 		throw dataTypeConversion("java.sql.Time");
 	}
 
+	public LocalTime	getLocalTime() throws StandardException
+	{
+	    throw dataTypeConversion("java.time.LocalTime");
+	}
+
 	public Timestamp	getTimestamp(java.util.Calendar cal) throws StandardException
 	{
 		throw dataTypeConversion("java.sql.Timestamp");
 	}
     
+	public LocalDateTime	getLocalDateTime() throws StandardException
+	{
+	    throw dataTypeConversion("java.time.LocalDateTime");
+	}
+    
     /**
      * Gets a trace representation of the CLOB for debugging.
      *
@@ -534,16 +552,31 @@ public class SQLClob
 		throwLangSetMismatch("java.sql.Time");
 	}
 	
+	public void setValue(LocalTime theValue) throws StandardException
+	{
+	    throwLangSetMismatch("java.time.LocalTime");
+	}
+	
 	public void setValue(Timestamp theValue, Calendar cal) throws StandardException
 	{
 		throwLangSetMismatch("java.sql.Timestamp");
 	}
 	
+	public void setValue(LocalDateTime theValue) throws StandardException
+	{
+	    throwLangSetMismatch("java.time.LocalDateTime");
+	}
+	
 	public void setValue(Date theValue, Calendar cal) throws StandardException
 	{
 		throwLangSetMismatch("java.sql.Date");
 	}
 	
+	public void setValue(LocalDate theValue) throws StandardException
+	{
+	    throwLangSetMismatch("java.time.LocalDate");
+	}
+	
 	public void setBigDecimal(BigDecimal bigDecimal) throws StandardException
 	{
 		throwLangSetMismatch("java.math.BigDecimal");

Modified: db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLDate.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLDate.java?rev=1918134&r1=1918133&r2=1918134&view=diff
==============================================================================
--- db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLDate.java (original)
+++ db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLDate.java Mon Jun  3 17:43:48 2024
@@ -53,6 +53,8 @@ import java.sql.SQLException;
 
 import java.text.DateFormat;
 import java.text.ParseException;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
 
 /**
  * This contains an instance of a SQL Date.
@@ -117,6 +119,16 @@ public final class SQLDate extends DataT
         return new Timestamp(getTimeInMillis(cal));
     }
 
+    public LocalDateTime getLocalDateTime() 
+    {
+        if (isNull())
+        {
+            return null;
+        }
+        
+        return SQLDate.getLocalDate(encodedDate).atStartOfDay();
+    }
+
     /**
      * Convert the date into a milli-seconds since the epoch
      * with the time set to 00:00 based upon the passed in Calendar.
@@ -146,6 +158,13 @@ public final class SQLDate extends DataT
                 getMonth(encodedDate)-1, getDay(encodedDate));     
     }
     
+    static LocalDate getLocalDate(int encodedDate)
+    {
+        // Note LocalDate uses 1 for January, Derby uses 1.
+        return LocalDate.of(getYear(encodedDate),
+                getMonth(encodedDate), getDay(encodedDate));
+    }
+    
 	/**
 		getObject returns the date value
 
@@ -536,6 +555,12 @@ public final class SQLDate extends DataT
 		encodedDate = computeEncodedDate((java.util.Date) value, cal);
 	}
 
+	public void setValue(LocalDate value) throws StandardException
+	{
+	    restoreToNull();
+	    encodedDate = computeEncodedDate(value);
+	}
+
 	/**
 		@see DateTimeDataValue#setValue
 
@@ -546,6 +571,16 @@ public final class SQLDate extends DataT
 		encodedDate = computeEncodedDate((java.util.Date) value, cal);
 	}
 
+	/**
+		@see DateTimeDataValue#setValue
+
+	 */
+	public void setValue(LocalDateTime value) throws StandardException
+	{
+	    restoreToNull();
+	    encodedDate = computeEncodedDate(value != null ? value.toLocalDate() : null);
+	}
+
 
 	public void setValue(String theValue)
 	    throws StandardException
@@ -708,6 +743,20 @@ public final class SQLDate extends DataT
 	}
 
 	/**
+	 * Get the value field.  We instantiate the field
+	 * on demand.
+	 *
+	 * @return	The value field.
+	 */
+	public LocalDate getLocalDate()
+	{
+	    if (isNull())
+	        return null;
+	    
+	    return SQLDate.getLocalDate(encodedDate);
+	}
+
+	/**
 	 * Get the year from the encodedDate.
 	 *
 	 * @param encodedDate	the encoded date
@@ -864,6 +913,11 @@ public final class SQLDate extends DataT
 		return SQLDate.computeEncodedDate(currentCal);
 	}
 
+    static int computeEncodedDate(LocalDate value) throws StandardException
+    {
+        return SQLDate.computeEncodedDate(value.getYear(), value.getMonthValue(), value.getDayOfMonth());
+    }
+
 
         /**
          * Implement the date SQL function: construct a SQL date from a string, number, or timestamp.

Modified: db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLTime.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLTime.java?rev=1918134&r1=1918133&r2=1918134&view=diff
==============================================================================
--- db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLTime.java (original)
+++ db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLTime.java Mon Jun  3 17:43:48 2024
@@ -52,6 +52,9 @@ import java.sql.SQLException;
 
 import java.text.DateFormat;
 import java.text.ParseException;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 
 /**
  * This contains an instance of a SQL Time
@@ -81,6 +84,7 @@ public final class SQLTime extends DataT
 	private int		encodedTime;
 	private int		encodedTimeFraction; //currently always 0 since we don't
 											 //support time precision
+    static final LocalDate TIME_EPOCH = LocalDate.of(1970, 1, 1);
 
 	/*
 	** DataValueDescriptor interface
@@ -152,6 +156,14 @@ public final class SQLTime extends DataT
 		}
 	}
 
+    public LocalDateTime getLocalDateTime()
+    {
+        if (isNull())
+            return null;
+        // Derby's resolution for the TIME type is only seconds.
+        return SQLTime.getLocalTime(encodedTime, 0).atDate(TIME_EPOCH);
+    }
+
 	public Object getObject()
 	{
 		return getTime( (Calendar) null);
@@ -587,6 +599,17 @@ public final class SQLTime extends DataT
 		encodedTime = computeEncodedTime(value, cal);
 	}
 
+    /**
+    @see DateTimeDataValue#setValue
+
+    @exception StandardException thrown on failure.
+     */
+    public void setValue(LocalTime value) throws StandardException
+    {
+        restoreToNull();
+        encodedTime = computeEncodedTime(value);
+    }
+
 	/**
 		@see DateTimeDataValue#setValue
 
@@ -598,6 +621,17 @@ public final class SQLTime extends DataT
 		encodedTime = computeEncodedTime(value, cal);
 	}
 
+    /**
+     @see DateTimeDataValue#setValue
+
+     @exception StandardException thrown on failure.
+     */
+    public void setValue(LocalDateTime value) throws StandardException
+    {
+        restoreToNull();
+        encodedTime = computeEncodedTime(value != null ? value.toLocalTime() : null);
+    }
+
 
 	public void setValue(String theValue)
 	    throws StandardException
@@ -767,6 +801,16 @@ public final class SQLTime extends DataT
         return getTime(cal, encodedTime, 0);
 	}
     
+    public LocalTime getLocalTime()
+    {
+        if (isNull())
+            return null;
+
+          // Derby's SQL TIME type only has second resolution
+          // so pass in 0 for nano-seconds
+        return getLocalTime(encodedTime, 0);
+    }
+    
     /**
      * Set the time portion of a date-time value into
      * the passed in Calendar object from its encodedTime
@@ -781,7 +825,15 @@ public final class SQLTime extends DataT
         cal.set(Calendar.MINUTE, getMinute(encodedTime));
         cal.set(Calendar.SECOND, getSecond(encodedTime));        
     }
-    
+
+    static LocalTime getLocalTime(int encodedTime, int nanos)
+    {
+        return LocalTime.of(getHour(encodedTime),
+            getMinute(encodedTime),
+            getSecond(encodedTime),
+            nanos);
+    }
+
     /**
      * Get a java.sql.Time object from an encoded time
      * and nano-second value. As required by JDBC the
@@ -856,6 +908,15 @@ public final class SQLTime extends DataT
                                   cal.get(Calendar.SECOND));
 	}
 
+    static int computeEncodedTime(LocalTime localTime) throws StandardException
+    {
+          if (localTime == null)
+              return -1;
+        return computeEncodedTime(localTime.getHour(),
+                localTime.getMinute(),
+                localTime.getSecond());
+    }
+
     static int computeEncodedTime( int hour, int minute, int second) throws StandardException
     {
         if( hour == 24)

Modified: db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLTimestamp.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLTimestamp.java?rev=1918134&r1=1918133&r2=1918134&view=diff
==============================================================================
--- db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLTimestamp.java (original)
+++ db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/SQLTimestamp.java Mon Jun  3 17:43:48 2024
@@ -49,6 +49,9 @@ import java.io.IOException;
 
 import java.text.DateFormat;
 import java.text.ParseException;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 
 /**
  * This contains an instance of a SQL Timestamp object.
@@ -145,6 +148,14 @@ public final class SQLTimestamp extends
 		return new Date(cal.getTimeInMillis());
 	}
 
+    public LocalDate	getLocalDate() throws StandardException
+    {
+        if (isNull())
+            return null;
+
+        return SQLDate.getLocalDate(encodedDate);
+    }
+
 	/**
 		getTime returns the time portion of the timestamp
 		Date is set to 1970-01-01
@@ -164,6 +175,16 @@ public final class SQLTimestamp extends
         return SQLTime.getTime(cal, encodedTime, nanos);
 	}
 
+    public LocalTime	getLocalTime() throws StandardException
+    {
+        if (isNull())
+            return null;
+
+        // Derby's SQL TIMESTAMP type supports resolution
+        // to nano-seconds
+        return SQLTime.getLocalTime(encodedTime, nanos);
+    }
+
 	public Object getObject()
 	{
 		return getTimestamp((Calendar) null);
@@ -632,8 +653,14 @@ public final class SQLTimestamp extends
         }
 		/* encodedTime and nanos are already set to zero by restoreToNull() */
 	}
-    
-    
+
+    public void setValue(LocalDate value) throws StandardException
+    {
+        restoreToNull();
+        encodedDate = computeEncodedDate(value);
+        /* encodedTime and nanos are already set to zero by restoreToNull() */
+    }
+
 	/**
 		@see DateTimeDataValue#setValue
 
@@ -645,6 +672,17 @@ public final class SQLTimestamp extends
 		setNumericTimestamp(value, cal);
 	}
 
+    /**
+     @see DateTimeDataValue#setValue
+    
+     */
+    public void setValue(LocalDateTime value) 
+            throws StandardException
+    {
+        restoreToNull();
+        setNumericTimestamp(value);
+    }
+
 
 	public void setValue(String theValue)
 	    throws StandardException
@@ -854,7 +892,23 @@ public final class SQLTimestamp extends
 
 		cal.set(Calendar.MILLISECOND, 0);
     } // end of setCalendar
-        
+
+    /**
+     * Get the value field.  We instantiate the field
+     * on demand.
+     *
+     * @return	The value field.
+     */
+    public LocalDateTime getLocalDateTime()
+    {
+        if (isNull())
+            return null;
+          
+          LocalDate localDate = SQLDate.getLocalDate(encodedDate);
+          LocalTime localTime = SQLTime.getLocalTime(encodedTime, nanos);
+          return LocalDateTime.of(localDate, localTime);
+    }
+
 	/**
 	 * Set the encoded values for the timestamp
 	 *
@@ -876,6 +930,21 @@ public final class SQLTimestamp extends
 		/* encoded date should already be 0 for null */
 	}
 
+    private void setNumericTimestamp(LocalDateTime value) throws StandardException
+    {
+        if (SanityManager.DEBUG)
+        {
+            SanityManager.ASSERT(isNull(), "setNumericTimestamp called when already set");
+        }
+        if (value != null)
+        {
+            encodedDate = computeEncodedDate(value.toLocalDate());
+            encodedTime = computeEncodedTime(value.toLocalTime());
+            nanos = value.getNano();
+        }
+        /* encoded date should already be 0 for null */
+    }
+
 	/**
 		computeEncodedDate sets the date in a Calendar object
 		and then uses the SQLDate function to compute an encoded date
@@ -893,6 +962,15 @@ public final class SQLTimestamp extends
 		currentCal.setTime(value);
 		return SQLDate.computeEncodedDate(currentCal);
 	}
+
+    private static int computeEncodedDate(java.time.LocalDate value) throws StandardException
+    {
+        if (value == null)
+            return 0;
+
+        return SQLDate.computeEncodedDate(value);
+    }
+
 	/**
 		computeEncodedTime extracts the hour, minute and seconds from
 		a java.util.Date value and encodes them as
@@ -908,7 +986,13 @@ public final class SQLTimestamp extends
 		return SQLTime.computeEncodedTime(currentCal);
 	}
 
-    
+    private static int computeEncodedTime(java.time.LocalTime value) throws StandardException
+    {
+        if (value == null)
+              return -1;
+        return SQLTime.computeEncodedTime(value);
+    }
+
     public void setInto(PreparedStatement ps, int position) throws SQLException, StandardException {
 
                   ps.setTimestamp(position, getTimestamp((Calendar) null));

Modified: db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/UserType.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/UserType.java?rev=1918134&r1=1918133&r2=1918134&view=diff
==============================================================================
--- db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/UserType.java (original)
+++ db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/iapi/types/UserType.java Mon Jun  3 17:43:48 2024
@@ -36,7 +36,9 @@ import org.apache.derby.iapi.services.ca
 import java.sql.Date;
 import java.sql.Time;
 import java.sql.Timestamp;
-
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.io.ObjectOutput;
 import java.io.ObjectInput;
 import java.io.IOException;
@@ -197,6 +199,21 @@ public class UserType extends DataType
 		return super.getDate(cal);
 	}
 
+    /**
+     @exception StandardException thrown on failure
+     */
+    public LocalDate	getLocalDate() throws StandardException
+    {
+        if (! isNull())
+        {
+            if (value instanceof LocalDate) 
+                return ((LocalDate)value);
+            else if (value instanceof LocalDateTime)
+                return ((LocalDateTime)value).toLocalDate();
+        }
+        return super.getLocalDate();
+    }
+
 	/**
 		@exception StandardException thrown on failure
 	 */
@@ -212,6 +229,21 @@ public class UserType extends DataType
 		return super.getTime(cal);
 	}
 
+    /**
+     @exception StandardException thrown on failure
+     */
+    public LocalTime	getLocalTime() throws StandardException
+    {
+        if (! isNull())
+        {
+            if (value instanceof LocalTime) 
+                return ((LocalTime)value);
+            else if (value instanceof LocalDateTime)
+                return ((LocalDateTime)value).toLocalTime();
+        }
+        return super.getLocalTime();
+    }
+
 	/**
 		@exception StandardException thrown on failure
 	 */
@@ -229,6 +261,23 @@ public class UserType extends DataType
 		return super.getTimestamp(cal);
 	}
 
+    /**
+     @exception StandardException thrown on failure
+     */
+    public LocalDateTime	getLocalDateTime() throws StandardException
+    {
+        if (! isNull())
+        {
+            if (value instanceof LocalDateTime) 
+                return ((LocalDateTime)value);
+            else if (value instanceof LocalDate)
+                return ((LocalDate)value).atStartOfDay();
+            else if (value instanceof LocalTime)
+                return ((LocalTime)value).atDate(SQLTime.TIME_EPOCH);
+        }
+        return super.getLocalDateTime();
+    }
+
 	void setObject(Object theValue)
     {
         setValue( theValue );

Modified: db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/impl/jdbc/EmbedCallableStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/impl/jdbc/EmbedCallableStatement.java?rev=1918134&r1=1918133&r2=1918134&view=diff
==============================================================================
--- db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/impl/jdbc/EmbedCallableStatement.java (original)
+++ db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/impl/jdbc/EmbedCallableStatement.java Mon Jun  3 17:43:48 2024
@@ -53,6 +53,9 @@ import java.sql.Statement;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.sql.Types;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.util.Calendar;
 import java.util.Map;
 import org.apache.derby.iapi.jdbc.CharacterStreamDescriptor;
@@ -476,6 +479,21 @@ public class EmbedCallableStatement exte
 
 	}
 
+    public LocalDate getLocalDate(int parameterIndex) throws SQLException
+    {
+        checkStatus();
+        try {
+            LocalDate v = getParms().
+                    getParameterForGet(parameterIndex-1).getLocalDate();
+            wasNull = (v == null);
+            return v;
+        } catch (StandardException e)
+        {
+            throw EmbedResultSet.noStateChangeException(e);
+        }
+        
+    }
+
     /**
 	 * @see CallableStatement#getTime
      * @exception SQLException NoOutputParameters thrown.
@@ -495,6 +513,21 @@ public class EmbedCallableStatement exte
 
 	}
 
+    private LocalTime getLocalTime(int parameterIndex) throws SQLException
+    {
+        checkStatus();
+        try {
+            LocalTime v = getParms().
+                    getParameterForGet(parameterIndex-1).getLocalTime();
+            wasNull = (v == null);
+            return v;
+        } catch (StandardException e)
+        {
+            throw EmbedResultSet.noStateChangeException(e);
+        }
+        
+    }
+
     /**
 	 * @see CallableStatement#getTimestamp
      * @exception SQLException NoOutputParameters thrown.
@@ -513,6 +546,22 @@ public class EmbedCallableStatement exte
 			throw EmbedResultSet.noStateChangeException(e);
 		}
 	}
+
+    private LocalDateTime getLocalDateTime(int parameterIndex)
+            throws SQLException 
+    {
+        checkStatus();
+        try {
+            LocalDateTime v = getParms().
+                    getParameterForGet(parameterIndex-1).getLocalDateTime();
+            wasNull = (v == null);
+            return v;
+        } catch (StandardException e)
+        {
+            throw EmbedResultSet.noStateChangeException(e);
+        }
+    }
+
     /**
      * Get the value of a SQL DATE parameter as a java.sql.Date object
      *
@@ -1866,10 +1915,16 @@ public class EmbedCallableStatement exte
             retval = getDouble(parameterIndex);
         } else if (Date.class.equals(type)) {
             retval = getDate(parameterIndex);
+        } else if (LocalDate.class.equals(type)) {
+            retval = getLocalDate(parameterIndex);
         } else if (Time.class.equals(type)) {
             retval = getTime(parameterIndex);
+        } else if (LocalTime.class.equals(type)) {
+            retval = getLocalTime(parameterIndex);
         } else if (Timestamp.class.equals(type)) {
             retval = getTimestamp(parameterIndex);
+        } else if (LocalDateTime.class.equals(type)) {
+            retval = getLocalDateTime(parameterIndex);
         } else if (Blob.class.equals(type)) {
             retval = getBlob(parameterIndex);
         } else if (Clob.class.equals(type)) {

Modified: db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java?rev=1918134&r1=1918133&r2=1918134&view=diff
==============================================================================
--- db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java (original)
+++ db/derby/code/branches/10.17/java/org.apache.derby.engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java Mon Jun  3 17:43:48 2024
@@ -67,6 +67,9 @@ import java.sql.Ref;
 import java.sql.RowId;
 import java.sql.SQLXML;
 import java.sql.Types;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 
 import org.apache.derby.iapi.jdbc.BrokeredConnectionControl;
 import org.apache.derby.iapi.jdbc.EnginePreparedStatement;
@@ -1347,14 +1350,26 @@ public class EmbedPreparedStatement exte
 			setDate(parameterIndex, (Date) x);
 			return;
 		}
+        if (x instanceof LocalDate) {
+            setLocalDate(parameterIndex, (LocalDate) x );
+            return;
+        }
 		if (x instanceof Time) {
 			setTime(parameterIndex, (Time) x);
 			return;
 		}
+        if (x instanceof LocalTime) {
+            setLocalTime(parameterIndex, (LocalTime) x);
+            return;
+        }
 		if (x instanceof Timestamp) {
 			setTimestamp(parameterIndex, (Timestamp) x);
 			return;
 		}
+        if (x instanceof LocalDateTime) {
+            setLocalDateTime(parameterIndex, (LocalDateTime) x);
+            return;
+        }
 
 		if (x instanceof Blob) {
 			setBlob(parameterIndex, (Blob) x);
@@ -1418,6 +1433,19 @@ public class EmbedPreparedStatement exte
 		}
 	}
 
+    private void setLocalDate(int parameterIndex, java.time.LocalDate x)
+            throws SQLException 
+    {
+        checkStatus();
+        try {
+            /* JDBC is one-based, DBMS is zero-based */
+            getParms().getParameterForSet(parameterIndex - 1).setValue(x);
+            
+        } catch (Throwable t) {
+            throw EmbedResultSet.noStateChangeException(t);
+        }
+    }
+
     /**
      * Set a parameter to a java.sql.Time value.  The driver converts this
      * to a SQL TIME value when it sends it to the database.
@@ -1439,6 +1467,19 @@ public class EmbedPreparedStatement exte
 		}
 	}
 
+    private void setLocalTime(int parameterIndex, java.time.LocalTime x)
+            throws SQLException 
+    {
+        checkStatus();
+        try {
+            /* JDBC is one-based, DBMS is zero-based */
+            getParms().getParameterForSet(parameterIndex - 1).setValue(x);
+            
+        } catch (Throwable t) {
+            throw EmbedResultSet.noStateChangeException(t);
+        }
+    }
+
     /**
      * Set a parameter to a java.sql.Timestamp value.  The driver
      * converts this to a SQL TIMESTAMP value when it sends it to the
@@ -1461,6 +1502,18 @@ public class EmbedPreparedStatement exte
 		}
 	}
 
+    public final void setLocalDateTime(int parameterIndex, java.time.LocalDateTime x)
+            throws SQLException 
+    {
+        checkStatus();
+        try {
+            /* JDBC is one-based, DBMS is zero-based */
+            getParms().getParameterForSet(parameterIndex - 1).setValue(x);
+            
+        } catch (StandardException t) {
+            throw EmbedResultSet.noStateChangeException(t);
+        }
+    }
 
     /**
      * JDBC 2.0