diff --git a/model/src/main/java/org/eclipse/daanse/sql/model/type/BestFitColumnType.java b/model/src/main/java/org/eclipse/daanse/sql/model/type/BestFitColumnType.java index 1935e45..d53e7d4 100644 --- a/model/src/main/java/org/eclipse/daanse/sql/model/type/BestFitColumnType.java +++ b/model/src/main/java/org/eclipse/daanse/sql/model/type/BestFitColumnType.java @@ -35,5 +35,18 @@ public enum BestFitColumnType { STRING, /** {@link java.math.BigDecimal} — for {@code DECIMAL}/{@code NUMERIC}. */ - DECIMAL + DECIMAL, + + /** + * {@link java.sql.Date} — for {@code DATE}, read with {@code getDate}. {@code getObject} hands a date over as the + * driver likes (a {@code java.sql.Date}, a {@code LocalDate}). + */ + DATE, + + /** + * {@link java.sql.Timestamp} — for {@code TIMESTAMP}, read with {@code getTimestamp}. {@code getObject} hands some + * timestamps over in a driver's own class (Oracle: {@code oracle.sql.TIMESTAMP}), which no format and no comparison + * of the engine knows. + */ + TIMESTAMP } diff --git a/statement/impl/src/main/java/org/eclipse/daanse/sql/statement/exec/ColumnAccessors.java b/statement/impl/src/main/java/org/eclipse/daanse/sql/statement/exec/ColumnAccessors.java index 1cd1fe5..3f60731 100644 --- a/statement/impl/src/main/java/org/eclipse/daanse/sql/statement/exec/ColumnAccessors.java +++ b/statement/impl/src/main/java/org/eclipse/daanse/sql/statement/exec/ColumnAccessors.java @@ -52,6 +52,8 @@ static Object read(ResultSet rs, int oneBasedCol, BestFitColumnType type) throws yield rs.wasNull() ? null : v; } case DECIMAL -> rs.getBigDecimal(oneBasedCol); + case DATE -> rs.getDate(oneBasedCol); + case TIMESTAMP -> rs.getTimestamp(oneBasedCol); case OBJECT -> rs.getObject(oneBasedCol); }; } diff --git a/statement/impl/src/test/java/org/eclipse/daanse/sql/statement/exec/ColumnAccessorsTest.java b/statement/impl/src/test/java/org/eclipse/daanse/sql/statement/exec/ColumnAccessorsTest.java new file mode 100644 index 0000000..efbb466 --- /dev/null +++ b/statement/impl/src/test/java/org/eclipse/daanse/sql/statement/exec/ColumnAccessorsTest.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * SmartCity Jena - initial + * Stefan Bischof (bipolis.org) - initial + */ +package org.eclipse.daanse.sql.statement.exec; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.sql.Date; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; + +import org.eclipse.daanse.sql.model.type.BestFitColumnType; +import org.junit.jupiter.api.Test; + +/** A temporal column is read with its getter, whatever class the driver's getObject would hand over. */ +class ColumnAccessorsTest { + + @Test + void aTimestampIsReadAsATimestamp() throws SQLException { + ResultSet rs = mock(ResultSet.class); + Timestamp timestamp = Timestamp.valueOf("2005-05-29 00:00:00"); + when(rs.getObject(1)).thenReturn(new Object() { + @Override + public String toString() { + return "a driver's own timestamp class"; + } + }); + when(rs.getTimestamp(1)).thenReturn(timestamp); + assertEquals(timestamp, ColumnAccessors.read(rs, 1, BestFitColumnType.TIMESTAMP)); + } + + @Test + void aDateIsReadAsADate() throws SQLException { + ResultSet rs = mock(ResultSet.class); + Date date = Date.valueOf("2008-04-29"); + when(rs.getObject(1)).thenReturn(date.toLocalDate()); + when(rs.getDate(1)).thenReturn(date); + assertEquals(date, ColumnAccessors.read(rs, 1, BestFitColumnType.DATE)); + } +}