This is an automated email from the ASF dual-hosted git repository.
jooger pushed a commit to branch jdbc_over_thin_sql
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/jdbc_over_thin_sql by this
push:
new dbece16fc9d IGNITE-26379 Jdbc. Add accessor methods to thin
client-backed ResultSet (datetime types) (#6565)
dbece16fc9d is described below
commit dbece16fc9df01f48e8318aafc71f9e5ab0f26c1
Author: Max Zhuravkov <[email protected]>
AuthorDate: Tue Sep 23 10:36:19 2025 +0300
IGNITE-26379 Jdbc. Add accessor methods to thin client-backed ResultSet
(datetime types) (#6565)
---
.../apache/ignite/internal/jdbc/JdbcResultSet.java | 25 +-
.../ignite/internal/jdbc2/JdbcResultSet.java | 287 +++++--
.../internal/jdbc/JdbcResultSetBaseSelfTest.java | 950 +++++++++++++++++++++
.../internal/jdbc2/JdbcResultSet2SelfTest.java | 30 +-
4 files changed, 1210 insertions(+), 82 deletions(-)
diff --git
a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcResultSet.java
b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcResultSet.java
index 3f05102064f..bb04f28be56 100644
---
a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcResultSet.java
+++
b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcResultSet.java
@@ -218,7 +218,7 @@ public class JdbcResultSet implements ResultSet {
/**
* Creates new result set.
*
- * @exception SQLException if a database access error occurs
+ * @throws SQLException if a database access error occurs
*/
@TestOnly
JdbcResultSet(List<List<Object>> rows, List<JdbcColumnMeta> meta,
JdbcStatement stmt) throws SQLException {
@@ -345,7 +345,6 @@ public class JdbcResultSet implements ResultSet {
* Close result set.
*
* @param removeFromResources If {@code true} cursor need to be removed
from client resources.
- *
* @throws SQLException On error.
*/
void close0(boolean removeFromResources) throws SQLException {
@@ -2226,7 +2225,7 @@ public class JdbcResultSet implements ResultSet {
/**
* Get object of given class.
*
- * @param colIdx Column index.
+ * @param colIdx Column index.
* @param targetCls Class representing the Java data type to convert the
designated column to.
* @return Converted object.
* @throws SQLException On error.
@@ -2376,20 +2375,28 @@ public class JdbcResultSet implements ResultSet {
return formatWithPrecision(DATE_TIME, value, colIdx, jdbcMeta);
}
- static String formatDate(LocalDate value) {
- return DATE.format(value);
+ static String formatDate(LocalDate value) throws SQLException {
+ try {
+ return DATE.format(value);
+ } catch (Exception e) {
+ throw new SQLException("Cannot convert to string: " + value,
SqlStateCode.CONVERSION_FAILED, e);
+ }
}
private static String formatWithPrecision(
- DateTimeFormatter formatter,
- TemporalAccessor value,
+ DateTimeFormatter formatter,
+ TemporalAccessor value,
int colIdx,
JdbcResultSetMetadata jdbcMeta
) throws SQLException {
StringBuilder sb = new StringBuilder();
- formatter.formatTo(value, sb);
+ try {
+ formatter.formatTo(value, sb);
+ } catch (Exception e) {
+ throw new SQLException("Cannot convert to string: " + value,
SqlStateCode.CONVERSION_FAILED, e);
+ }
int precision = jdbcMeta.getPrecision(colIdx);
if (precision <= 0) {
@@ -2400,7 +2407,7 @@ public class JdbcResultSet implements ResultSet {
// Append nano seconds according to the specified precision.
long nanos = value.getLong(ChronoField.NANO_OF_SECOND);
- long scaled = nanos / (long) Math.pow(10, 9 - precision);
+ long scaled = nanos / (long) Math.pow(10, 9 - precision);
sb.append('.');
for (int i = 0; i < precision; i++) {
diff --git
a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
index 31f00ee846b..b1f59cf45e9 100644
---
a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
+++
b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc2/JdbcResultSet.java
@@ -40,14 +40,23 @@ import java.sql.SQLXML;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
-import java.time.temporal.Temporal;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.temporal.ChronoField;
+import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
-import java.util.UUID;
+import java.util.function.Supplier;
import org.apache.ignite.internal.jdbc.proto.SqlStateCode;
import org.apache.ignite.internal.lang.IgniteExceptionMapperUtil;
import org.apache.ignite.internal.sql.ResultSetMetadataImpl;
+import org.apache.ignite.internal.util.StringUtils;
import org.apache.ignite.sql.ColumnMetadata;
import org.apache.ignite.sql.ColumnType;
import org.apache.ignite.sql.ResultSetMetadata;
@@ -75,6 +84,8 @@ public class JdbcResultSet implements ResultSet {
private final ResultSetMetadata rsMetadata;
+ private final Supplier<ZoneId> zoneIdSupplier;
+
private final Statement statement;
private int fetchSize;
@@ -94,17 +105,20 @@ public class JdbcResultSet implements ResultSet {
*/
public JdbcResultSet(
org.apache.ignite.sql.ResultSet<SqlRow> rs,
- Statement statement
+ Statement statement,
+ Supplier<ZoneId> zoneIdSupplier
) {
this.rs = rs;
ResultSetMetadata metadata = rs.metadata();
this.rsMetadata = metadata != null ? metadata : EMPTY_METADATA;
+ this.zoneIdSupplier = zoneIdSupplier;
this.statement = statement;
this.currentRow = null;
this.closed = false;
this.wasNull = false;
+ this.jdbcMeta = new JdbcResultSetMetadata(rsMetadata);
}
@Override
@@ -150,24 +164,41 @@ public class JdbcResultSet implements ResultSet {
/** {@inheritDoc} */
@Override
+ @Nullable
public String getString(int colIdx) throws SQLException {
ensureNotClosed();
ensureHasCurrentRow();
- Object value = getValue(colIdx);
- if (value == null) {
+ Object val = getValue(colIdx);
+ if (val == null) {
return null;
}
- if (value instanceof Temporal || value instanceof byte[] || value
instanceof UUID) {
- throw new UnsupportedOperationException();
- } else {
- return String.valueOf(value);
+ ColumnType columnType = getColumnType(colIdx);
+ try {
+ switch (columnType) {
+ case DATE:
+ return Formatters.formatDate((LocalDate) val);
+ case TIME:
+ return Formatters.formatTime((LocalTime) val,
getColumnPrecision(colIdx));
+ case DATETIME:
+ return Formatters.formatDateTime((LocalDateTime) val,
getColumnPrecision(colIdx));
+ case TIMESTAMP:
+ LocalDateTime localDateTime =
instantWithLocalTimeZone((Instant) val);
+ return Formatters.formatDateTime(localDateTime,
getColumnPrecision(colIdx));
+ case BYTE_ARRAY:
+ return StringUtils.toHexString((byte[]) val);
+ default:
+ return String.valueOf(val);
+ }
+ } catch (Exception e) {
+ throw conversionError("string", e);
}
}
/** {@inheritDoc} */
@Override
+ @Nullable
public String getString(String colLb) throws SQLException {
int colIdx = findColumn(colLb);
@@ -205,7 +236,7 @@ public class JdbcResultSet implements ResultSet {
// Fallthrough
}
- throw new SQLException("Cannot convert to boolean: " + val,
SqlStateCode.CONVERSION_FAILED);
+ throw conversionError("boolean", val);
}
/** {@inheritDoc} */
@@ -537,10 +568,10 @@ public class JdbcResultSet implements ResultSet {
try {
return new BigDecimal(val.toString());
} catch (Exception e) {
- throw new SQLException("Cannot convert to BigDecimal: " +
val, SqlStateCode.CONVERSION_FAILED, e);
+ throw conversionError("BigDecimal", val, e);
}
default:
- throw new SQLException("Cannot convert to BigDecimal: " + val,
SqlStateCode.CONVERSION_FAILED);
+ throw conversionError("BigDecimal", val);
}
}
@@ -574,118 +605,163 @@ public class JdbcResultSet implements ResultSet {
/** {@inheritDoc} */
@Override
public byte[] getBytes(String colLb) throws SQLException {
- ensureNotClosed();
- ensureHasCurrentRow();
+ int colIdx = findColumn(colLb);
- throw new UnsupportedOperationException();
+ return getBytes(colIdx);
}
/** {@inheritDoc} */
@Override
+ @Nullable
public Date getDate(int colIdx) throws SQLException {
- ensureNotClosed();
- ensureHasCurrentRow();
+ Object val = getValue(colIdx);
- throw new UnsupportedOperationException();
+ if (val == null) {
+ return null;
+ }
+
+ ColumnType columnType = getColumnType(colIdx);
+ switch (columnType) {
+ case TIME:
+ return new Date(Time.valueOf((LocalTime) val).getTime());
+ case DATE:
+ return Date.valueOf((LocalDate) val);
+ case DATETIME:
+ return Date.valueOf(((LocalDateTime) val).toLocalDate());
+ case TIMESTAMP:
+ LocalDateTime localDateTime =
instantWithLocalTimeZone((Instant) val);
+ return Date.valueOf(localDateTime.toLocalDate());
+ default:
+ throw conversionError("date", val);
+ }
}
/** {@inheritDoc} */
@Override
+ @Nullable
public Date getDate(String colLb) throws SQLException {
- ensureNotClosed();
- ensureHasCurrentRow();
+ int colIdx = findColumn(colLb);
- throw new UnsupportedOperationException();
+ return getDate(colIdx);
}
/** {@inheritDoc} */
@Override
+ @Nullable
public Date getDate(int colIdx, Calendar cal) throws SQLException {
- ensureNotClosed();
- ensureHasCurrentRow();
-
- throw new UnsupportedOperationException();
+ return getDate(colIdx);
}
/** {@inheritDoc} */
@Override
+ @Nullable
public Date getDate(String colLb, Calendar cal) throws SQLException {
- ensureNotClosed();
- ensureHasCurrentRow();
+ int colIdx = findColumn(colLb);
- throw new UnsupportedOperationException();
+ return getDate(colIdx);
}
/** {@inheritDoc} */
@Override
+ @Nullable
public Time getTime(int colIdx) throws SQLException {
- ensureNotClosed();
- ensureHasCurrentRow();
+ Object val = getValue(colIdx);
- throw new UnsupportedOperationException();
+ if (val == null) {
+ return null;
+ }
+
+ ColumnType columnType = getColumnType(colIdx);
+ switch (columnType) {
+ case TIME:
+ return Time.valueOf((LocalTime) val);
+ case DATE:
+ return new Time(Date.valueOf((LocalDate) val).getTime());
+ case DATETIME:
+ return Time.valueOf(((LocalDateTime) val).toLocalTime());
+ case TIMESTAMP:
+ LocalDateTime localDateTime =
instantWithLocalTimeZone((Instant) val);
+ LocalTime localTime = localDateTime.toLocalTime();
+ return Time.valueOf(localTime);
+ default:
+ throw conversionError("time", val);
+ }
}
/** {@inheritDoc} */
@Override
+ @Nullable
public Time getTime(String colLb) throws SQLException {
- ensureNotClosed();
- ensureHasCurrentRow();
+ int colIdx = findColumn(colLb);
- throw new UnsupportedOperationException();
+ return getTime(colIdx);
}
/** {@inheritDoc} */
@Override
+ @Nullable
public Time getTime(int colIdx, Calendar cal) throws SQLException {
- ensureNotClosed();
- ensureHasCurrentRow();
-
- throw new UnsupportedOperationException();
+ return getTime(colIdx);
}
/** {@inheritDoc} */
@Override
+ @Nullable
public Time getTime(String colLb, Calendar cal) throws SQLException {
- ensureNotClosed();
- ensureHasCurrentRow();
+ int colIdx = findColumn(colLb);
- throw new UnsupportedOperationException();
+ return getTime(colIdx);
}
/** {@inheritDoc} */
@Override
+ @Nullable
public Timestamp getTimestamp(int colIdx) throws SQLException {
- ensureNotClosed();
- ensureHasCurrentRow();
+ Object val = getValue(colIdx);
- throw new UnsupportedOperationException();
+ if (val == null) {
+ return null;
+ }
+
+ ColumnType columnType = getColumnType(colIdx);
+ switch (columnType) {
+ case TIME:
+ return new Timestamp(Time.valueOf((LocalTime) val).getTime());
+ case DATE:
+ return new Timestamp(Date.valueOf((LocalDate) val).getTime());
+ case DATETIME:
+ return Timestamp.valueOf((LocalDateTime) val);
+ case TIMESTAMP:
+ LocalDateTime localDateTime =
instantWithLocalTimeZone((Instant) val);
+ return Timestamp.valueOf(localDateTime);
+ default:
+ throw conversionError("timestamp", val);
+ }
}
/** {@inheritDoc} */
@Override
+ @Nullable
public Timestamp getTimestamp(int colIdx, Calendar cal) throws
SQLException {
- ensureNotClosed();
- ensureHasCurrentRow();
-
return getTimestamp(colIdx);
}
/** {@inheritDoc} */
@Override
+ @Nullable
public Timestamp getTimestamp(String colLb, Calendar cal) throws
SQLException {
- ensureNotClosed();
- ensureHasCurrentRow();
+ int colIdx = findColumn(colLb);
- throw new UnsupportedOperationException();
+ return getTimestamp(colIdx);
}
/** {@inheritDoc} */
@Override
+ @Nullable
public Timestamp getTimestamp(String colLb) throws SQLException {
- ensureNotClosed();
- ensureHasCurrentRow();
+ int colIdx = findColumn(colLb);
- throw new UnsupportedOperationException();
+ return getTimestamp(colIdx);
}
/** {@inheritDoc} */
@@ -764,7 +840,7 @@ public class JdbcResultSet implements ResultSet {
public ResultSetMetaData getMetaData() throws SQLException {
ensureNotClosed();
- return initMetadata();
+ return jdbcMeta;
}
/** {@inheritDoc} */
@@ -1860,6 +1936,7 @@ public class JdbcResultSet implements ResultSet {
/** {@inheritDoc} */
@Override
+ @Nullable
public String getNString(int colIdx) throws SQLException {
return getString(colIdx);
}
@@ -2037,18 +2114,17 @@ public class JdbcResultSet implements ResultSet {
}
}
- private JdbcResultSetMetadata initMetadata() {
- if (jdbcMeta == null) {
- jdbcMeta = new JdbcResultSetMetadata(rsMetadata);
- }
- return jdbcMeta;
- }
-
private ColumnType getColumnType(int colIdx) {
ColumnMetadata column = rsMetadata.columns().get(colIdx - 1);
return column.type();
}
+ private int getColumnPrecision(int colIdx) {
+ int precision = rsMetadata.columns().get(colIdx - 1).precision();
+ assert precision <= 9 : "Precision is out of range. Precision: " +
precision + ". Column: " + colIdx;
+ return precision;
+ }
+
private static long getLongValue(long val, String typeName, long min, long
max) throws SQLException {
if (val < min || val > max) {
throw conversionError(typeName, val);
@@ -2101,4 +2177,93 @@ public class JdbcResultSet implements ResultSet {
private static SQLException conversionError(String typeName, Object val,
@Nullable Throwable cause) {
return new SQLException(format("Cannot convert to {}: {}", typeName,
val), SqlStateCode.CONVERSION_FAILED, cause);
}
+
+ private LocalDateTime instantWithLocalTimeZone(Instant val) {
+ ZoneId zoneId = zoneIdSupplier.get();
+ if (zoneId == null) {
+ zoneId = ZoneId.systemDefault();
+ }
+ return LocalDateTime.ofInstant(val, zoneId);
+ }
+
+ private static class Formatters {
+ static final DateTimeFormatter TIME = new DateTimeFormatterBuilder()
+ .appendValue(ChronoField.HOUR_OF_DAY, 2)
+ .appendLiteral(':')
+ .appendValue(ChronoField.MINUTE_OF_HOUR, 2)
+ .appendLiteral(':')
+ .appendValue(ChronoField.SECOND_OF_MINUTE, 2)
+ .toFormatter();
+
+ static final DateTimeFormatter DATE = new DateTimeFormatterBuilder()
+ .appendValue(ChronoField.YEAR, 4)
+ .appendLiteral('-')
+ .appendValue(ChronoField.MONTH_OF_YEAR, 2)
+ .appendLiteral('-')
+ .appendValue(ChronoField.DAY_OF_MONTH, 2)
+ .toFormatter();
+
+ static final DateTimeFormatter DATE_TIME = new
DateTimeFormatterBuilder()
+ .appendValue(ChronoField.YEAR, 4)
+ .appendLiteral('-')
+ .appendValue(ChronoField.MONTH_OF_YEAR, 2)
+ .appendLiteral('-')
+ .appendValue(ChronoField.DAY_OF_MONTH, 2)
+ .appendLiteral(' ')
+ .appendValue(ChronoField.HOUR_OF_DAY, 2)
+ .appendLiteral(':')
+ .appendValue(ChronoField.MINUTE_OF_HOUR, 2)
+ .appendLiteral(':')
+ .appendValue(ChronoField.SECOND_OF_MINUTE, 2)
+ .toFormatter();
+
+ static String formatTime(LocalTime value, int precision) {
+ return formatWithPrecision(TIME, value, precision);
+ }
+
+ static String formatDateTime(LocalDateTime value, int precision) {
+ return formatWithPrecision(DATE_TIME, value, precision);
+ }
+
+ static String formatDate(LocalDate value) {
+ return DATE.format(value);
+ }
+
+ private static String formatWithPrecision(
+ DateTimeFormatter formatter,
+ TemporalAccessor value,
+ int precision
+ ) {
+
+ StringBuilder sb = new StringBuilder();
+
+ formatter.formatTo(value, sb);
+
+ if (precision <= 0) {
+ return sb.toString();
+ }
+
+ // Append nano seconds according to the specified precision.
+ long nanos = value.getLong(ChronoField.NANO_OF_SECOND);
+ long scaled = nanos / (long) Math.pow(10, 9 - precision);
+
+ sb.append('.');
+ for (int i = 0; i < precision; i++) {
+ sb.append('0');
+ }
+
+ int pos = precision - 1;
+ int start = sb.length() - precision;
+
+ do {
+ int digit = (int) (scaled % 10);
+ char c = (char) ('0' + digit);
+ sb.setCharAt(start + pos, c);
+ scaled /= 10;
+ pos--;
+ } while (scaled != 0 && pos >= 0);
+
+ return sb.toString();
+ }
+ }
}
diff --git
a/modules/jdbc/src/test/java/org/apache/ignite/internal/jdbc/JdbcResultSetBaseSelfTest.java
b/modules/jdbc/src/test/java/org/apache/ignite/internal/jdbc/JdbcResultSetBaseSelfTest.java
index 48efc7cf7ed..5347a1b8413 100644
---
a/modules/jdbc/src/test/java/org/apache/ignite/internal/jdbc/JdbcResultSetBaseSelfTest.java
+++
b/modules/jdbc/src/test/java/org/apache/ignite/internal/jdbc/JdbcResultSetBaseSelfTest.java
@@ -41,11 +41,16 @@ import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.Time;
import java.sql.Timestamp;
+import java.time.Clock;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoField;
+import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
@@ -157,6 +162,24 @@ public abstract class JdbcResultSetBaseSelfTest extends
BaseIgniteAbstractTest {
assertEquals(strVal, rs.getNString(1));
assertEquals(strVal, rs.getNString("C"));
+ expectSqlConversionError(() -> rs.getDate(1), "date");
+ expectSqlConversionError(() -> rs.getDate("C"), "date");
+
+ expectSqlConversionError(() -> rs.getTime(1), "time");
+ expectSqlConversionError(() -> rs.getTime("C"), "time");
+
+ expectSqlConversionError(() -> rs.getTimestamp(1), "timestamp");
+ expectSqlConversionError(() -> rs.getTimestamp("C"), "timestamp");
+
+ expectSqlConversionError(() -> rs.getDate(1,
Calendar.getInstance()), "date");
+ expectSqlConversionError(() -> rs.getDate("C",
Calendar.getInstance()), "date");
+
+ expectSqlConversionError(() -> rs.getTime(1,
Calendar.getInstance()), "time");
+ expectSqlConversionError(() -> rs.getTime("C",
Calendar.getInstance()), "time");
+
+ expectSqlConversionError(() -> rs.getTimestamp(1,
Calendar.getInstance()), "timestamp");
+ expectSqlConversionError(() -> rs.getTimestamp("C",
Calendar.getInstance()), "timestamp");
+
// getObject
assertEquals(boolValue, rs.getObject(1));
@@ -186,6 +209,15 @@ public abstract class JdbcResultSetBaseSelfTest extends
BaseIgniteAbstractTest {
assertEquals(strVal, rs.getObject(1, String.class));
assertEquals(strVal, rs.getObject("C", String.class));
+ expectSqlConversionError(() -> rs.getObject(1, Date.class),
"date");
+ expectSqlConversionError(() -> rs.getObject("C", Date.class),
"date");
+
+ expectSqlConversionError(() -> rs.getObject(1, Time.class),
"time");
+ expectSqlConversionError(() -> rs.getObject("C", Time.class),
"time");
+
+ expectSqlConversionError(() -> rs.getObject(1, Timestamp.class),
"timestamp");
+ expectSqlConversionError(() -> rs.getObject("C", Timestamp.class),
"timestamp");
+
expectSqlConversionError(() -> rs.getObject(1, UUID.class),
"java.util.UUID");
expectSqlConversionError(() -> rs.getObject("C", UUID.class),
"java.util.UUID");
}
@@ -280,6 +312,24 @@ public abstract class JdbcResultSetBaseSelfTest extends
BaseIgniteAbstractTest {
assertEquals(strVal, rs.getNString(1));
assertEquals(strVal, rs.getNString("C"));
+ expectSqlConversionError(() -> rs.getDate(1), "date");
+ expectSqlConversionError(() -> rs.getDate("C"), "date");
+
+ expectSqlConversionError(() -> rs.getTime(1), "time");
+ expectSqlConversionError(() -> rs.getTime("C"), "time");
+
+ expectSqlConversionError(() -> rs.getTimestamp(1), "timestamp");
+ expectSqlConversionError(() -> rs.getTimestamp("C"), "timestamp");
+
+ expectSqlConversionError(() -> rs.getDate(1,
Calendar.getInstance()), "date");
+ expectSqlConversionError(() -> rs.getDate("C",
Calendar.getInstance()), "date");
+
+ expectSqlConversionError(() -> rs.getTime(1,
Calendar.getInstance()), "time");
+ expectSqlConversionError(() -> rs.getTime("C",
Calendar.getInstance()), "time");
+
+ expectSqlConversionError(() -> rs.getTimestamp(1,
Calendar.getInstance()), "timestamp");
+ expectSqlConversionError(() -> rs.getTimestamp("C",
Calendar.getInstance()), "timestamp");
+
// getObject
assertEquals(value, rs.getObject(1));
@@ -309,6 +359,15 @@ public abstract class JdbcResultSetBaseSelfTest extends
BaseIgniteAbstractTest {
assertEquals(strVal, rs.getObject(1, String.class));
assertEquals(strVal, rs.getObject("C", String.class));
+ expectSqlConversionError(() -> rs.getObject(1, Date.class),
"date");
+ expectSqlConversionError(() -> rs.getObject("C", Date.class),
"date");
+
+ expectSqlConversionError(() -> rs.getObject(1, Time.class),
"time");
+ expectSqlConversionError(() -> rs.getObject("C", Time.class),
"time");
+
+ expectSqlConversionError(() -> rs.getObject(1, Timestamp.class),
"timestamp");
+ expectSqlConversionError(() -> rs.getObject("C", Timestamp.class),
"timestamp");
+
expectSqlConversionError(() -> rs.getObject(1, UUID.class),
"java.util.UUID");
expectSqlConversionError(() -> rs.getObject("C", UUID.class),
"java.util.UUID");
}
@@ -478,6 +537,24 @@ public abstract class JdbcResultSetBaseSelfTest extends
BaseIgniteAbstractTest {
assertEquals(strVal, rs.getNString(1));
assertEquals(strVal, rs.getNString("C"));
+ expectSqlConversionError(() -> rs.getDate(1), "date");
+ expectSqlConversionError(() -> rs.getDate("C"), "date");
+
+ expectSqlConversionError(() -> rs.getTime(1), "time");
+ expectSqlConversionError(() -> rs.getTime("C"), "time");
+
+ expectSqlConversionError(() -> rs.getTimestamp(1), "timestamp");
+ expectSqlConversionError(() -> rs.getTimestamp("C"), "timestamp");
+
+ expectSqlConversionError(() -> rs.getDate(1,
Calendar.getInstance()), "date");
+ expectSqlConversionError(() -> rs.getDate("C",
Calendar.getInstance()), "date");
+
+ expectSqlConversionError(() -> rs.getTime(1,
Calendar.getInstance()), "time");
+ expectSqlConversionError(() -> rs.getTime("C",
Calendar.getInstance()), "time");
+
+ expectSqlConversionError(() -> rs.getTimestamp(1,
Calendar.getInstance()), "timestamp");
+ expectSqlConversionError(() -> rs.getTimestamp("C",
Calendar.getInstance()), "timestamp");
+
// getObject
assertEquals(value, rs.getObject(1));
@@ -509,6 +586,15 @@ public abstract class JdbcResultSetBaseSelfTest extends
BaseIgniteAbstractTest {
assertEquals(strVal, rs.getObject(1, String.class));
assertEquals(strVal, rs.getObject("C", String.class));
+ expectSqlConversionError(() -> rs.getObject(1, Date.class),
"date");
+ expectSqlConversionError(() -> rs.getObject("C", Date.class),
"date");
+
+ expectSqlConversionError(() -> rs.getObject(1, Time.class),
"time");
+ expectSqlConversionError(() -> rs.getObject("C", Time.class),
"time");
+
+ expectSqlConversionError(() -> rs.getObject(1, Timestamp.class),
"timestamp");
+ expectSqlConversionError(() -> rs.getObject("C", Timestamp.class),
"timestamp");
+
expectSqlConversionError(() -> rs.getObject(1, UUID.class),
"java.util.UUID");
expectSqlConversionError(() -> rs.getObject("C", UUID.class),
"java.util.UUID");
}
@@ -682,6 +768,24 @@ public abstract class JdbcResultSetBaseSelfTest extends
BaseIgniteAbstractTest {
assertEquals(strVal, rs.getNString(1));
assertEquals(strVal, rs.getNString("C"));
+ expectSqlConversionError(() -> rs.getDate(1), "date");
+ expectSqlConversionError(() -> rs.getDate("C"), "date");
+
+ expectSqlConversionError(() -> rs.getTime(1), "time");
+ expectSqlConversionError(() -> rs.getTime("C"), "time");
+
+ expectSqlConversionError(() -> rs.getTimestamp(1), "timestamp");
+ expectSqlConversionError(() -> rs.getTimestamp("C"), "timestamp");
+
+ expectSqlConversionError(() -> rs.getDate(1,
Calendar.getInstance()), "date");
+ expectSqlConversionError(() -> rs.getDate("C",
Calendar.getInstance()), "date");
+
+ expectSqlConversionError(() -> rs.getTime(1,
Calendar.getInstance()), "time");
+ expectSqlConversionError(() -> rs.getTime("C",
Calendar.getInstance()), "time");
+
+ expectSqlConversionError(() -> rs.getTimestamp(1,
Calendar.getInstance()), "timestamp");
+ expectSqlConversionError(() -> rs.getTimestamp("C",
Calendar.getInstance()), "timestamp");
+
// getObject
assertEquals(value, rs.getObject(1));
@@ -715,6 +819,15 @@ public abstract class JdbcResultSetBaseSelfTest extends
BaseIgniteAbstractTest {
assertEquals(strVal, rs.getObject(1, String.class));
assertEquals(strVal, rs.getObject("C", String.class));
+ expectSqlConversionError(() -> rs.getObject(1, Date.class),
"date");
+ expectSqlConversionError(() -> rs.getObject("C", Date.class),
"date");
+
+ expectSqlConversionError(() -> rs.getObject(1, Time.class),
"time");
+ expectSqlConversionError(() -> rs.getObject("C", Time.class),
"time");
+
+ expectSqlConversionError(() -> rs.getObject(1, Timestamp.class),
"timestamp");
+ expectSqlConversionError(() -> rs.getObject("C", Timestamp.class),
"timestamp");
+
expectSqlConversionError(() -> rs.getObject(1, UUID.class),
"java.util.UUID");
expectSqlConversionError(() -> rs.getObject("C", UUID.class),
"java.util.UUID");
}
@@ -888,6 +1001,24 @@ public abstract class JdbcResultSetBaseSelfTest extends
BaseIgniteAbstractTest {
assertEquals(strVal, rs.getNString(1));
assertEquals(strVal, rs.getNString("C"));
+ expectSqlConversionError(() -> rs.getDate(1), "date");
+ expectSqlConversionError(() -> rs.getDate("C"), "date");
+
+ expectSqlConversionError(() -> rs.getTime(1), "time");
+ expectSqlConversionError(() -> rs.getTime("C"), "time");
+
+ expectSqlConversionError(() -> rs.getTimestamp(1), "timestamp");
+ expectSqlConversionError(() -> rs.getTimestamp("C"), "timestamp");
+
+ expectSqlConversionError(() -> rs.getDate(1,
Calendar.getInstance()), "date");
+ expectSqlConversionError(() -> rs.getDate("C",
Calendar.getInstance()), "date");
+
+ expectSqlConversionError(() -> rs.getTime(1,
Calendar.getInstance()), "time");
+ expectSqlConversionError(() -> rs.getTime("C",
Calendar.getInstance()), "time");
+
+ expectSqlConversionError(() -> rs.getTimestamp(1,
Calendar.getInstance()), "timestamp");
+ expectSqlConversionError(() -> rs.getTimestamp("C",
Calendar.getInstance()), "timestamp");
+
// getObject
assertEquals(value, rs.getObject(1));
@@ -923,6 +1054,15 @@ public abstract class JdbcResultSetBaseSelfTest extends
BaseIgniteAbstractTest {
assertEquals(strVal, rs.getObject(1, String.class));
assertEquals(strVal, rs.getObject("C", String.class));
+ expectSqlConversionError(() -> rs.getObject(1, Date.class),
"date");
+ expectSqlConversionError(() -> rs.getObject("C", Date.class),
"date");
+
+ expectSqlConversionError(() -> rs.getObject(1, Time.class),
"time");
+ expectSqlConversionError(() -> rs.getObject("C", Time.class),
"time");
+
+ expectSqlConversionError(() -> rs.getObject(1, Timestamp.class),
"timestamp");
+ expectSqlConversionError(() -> rs.getObject("C", Timestamp.class),
"timestamp");
+
expectSqlConversionError(() -> rs.getObject(1, UUID.class),
"java.util.UUID");
expectSqlConversionError(() -> rs.getObject("C", UUID.class),
"java.util.UUID");
}
@@ -1081,7 +1221,9 @@ public abstract class JdbcResultSetBaseSelfTest extends
BaseIgniteAbstractTest {
assertEquals(decimalVal, rs.getBigDecimal(1));
assertEquals(decimalVal, rs.getBigDecimal("C"));
+ //noinspection deprecation
assertEquals(decimalScaledVal, rs.getBigDecimal(1, 2));
+ //noinspection deprecation
assertEquals(decimalScaledVal, rs.getBigDecimal("C", 2));
assertEquals(strVal, rs.getString(1));
@@ -1090,6 +1232,24 @@ public abstract class JdbcResultSetBaseSelfTest extends
BaseIgniteAbstractTest {
assertEquals(strVal, rs.getNString(1));
assertEquals(strVal, rs.getNString("C"));
+ expectSqlConversionError(() -> rs.getDate(1), "date");
+ expectSqlConversionError(() -> rs.getDate("C"), "date");
+
+ expectSqlConversionError(() -> rs.getTime(1), "time");
+ expectSqlConversionError(() -> rs.getTime("C"), "time");
+
+ expectSqlConversionError(() -> rs.getTimestamp(1), "timestamp");
+ expectSqlConversionError(() -> rs.getTimestamp("C"), "timestamp");
+
+ expectSqlConversionError(() -> rs.getDate(1,
Calendar.getInstance()), "date");
+ expectSqlConversionError(() -> rs.getDate("C",
Calendar.getInstance()), "date");
+
+ expectSqlConversionError(() -> rs.getTime(1,
Calendar.getInstance()), "time");
+ expectSqlConversionError(() -> rs.getTime("C",
Calendar.getInstance()), "time");
+
+ expectSqlConversionError(() -> rs.getTimestamp(1,
Calendar.getInstance()), "timestamp");
+ expectSqlConversionError(() -> rs.getTimestamp("C",
Calendar.getInstance()), "timestamp");
+
// getObject
assertEquals(value, rs.getObject(1));
@@ -1127,6 +1287,15 @@ public abstract class JdbcResultSetBaseSelfTest extends
BaseIgniteAbstractTest {
assertEquals(strVal, rs.getObject(1, String.class));
assertEquals(strVal, rs.getObject("C", String.class));
+ expectSqlConversionError(() -> rs.getObject(1, Date.class),
"date");
+ expectSqlConversionError(() -> rs.getObject("C", Date.class),
"date");
+
+ expectSqlConversionError(() -> rs.getObject(1, Time.class),
"time");
+ expectSqlConversionError(() -> rs.getObject("C", Time.class),
"time");
+
+ expectSqlConversionError(() -> rs.getObject(1, Timestamp.class),
"timestamp");
+ expectSqlConversionError(() -> rs.getObject("C", Timestamp.class),
"timestamp");
+
expectSqlConversionError(() -> rs.getObject(1, UUID.class),
"java.util.UUID");
expectSqlConversionError(() -> rs.getObject("C", UUID.class),
"java.util.UUID");
}
@@ -1256,7 +1425,9 @@ public abstract class JdbcResultSetBaseSelfTest extends
BaseIgniteAbstractTest {
//noinspection NumericCastThatLosesPrecision
assertEquals((long) value, rs.getLong("C"));
+ //noinspection NumericCastThatLosesPrecision
assertEquals((float) value, rs.getFloat(1));
+ //noinspection NumericCastThatLosesPrecision
assertEquals((float) value, rs.getFloat("C"));
assertEquals(value, rs.getDouble(1));
@@ -1276,6 +1447,24 @@ public abstract class JdbcResultSetBaseSelfTest extends
BaseIgniteAbstractTest {
assertEquals(strVal, rs.getNString(1));
assertEquals(strVal, rs.getNString("C"));
+ expectSqlConversionError(() -> rs.getDate(1), "date");
+ expectSqlConversionError(() -> rs.getDate("C"), "date");
+
+ expectSqlConversionError(() -> rs.getTime(1), "time");
+ expectSqlConversionError(() -> rs.getTime("C"), "time");
+
+ expectSqlConversionError(() -> rs.getTimestamp(1), "timestamp");
+ expectSqlConversionError(() -> rs.getTimestamp("C"), "timestamp");
+
+ expectSqlConversionError(() -> rs.getDate(1,
Calendar.getInstance()), "date");
+ expectSqlConversionError(() -> rs.getDate("C",
Calendar.getInstance()), "date");
+
+ expectSqlConversionError(() -> rs.getTime(1,
Calendar.getInstance()), "time");
+ expectSqlConversionError(() -> rs.getTime("C",
Calendar.getInstance()), "time");
+
+ expectSqlConversionError(() -> rs.getTimestamp(1,
Calendar.getInstance()), "timestamp");
+ expectSqlConversionError(() -> rs.getTimestamp("C",
Calendar.getInstance()), "timestamp");
+
// getObject
assertEquals(value, rs.getObject(1));
@@ -1315,6 +1504,15 @@ public abstract class JdbcResultSetBaseSelfTest extends
BaseIgniteAbstractTest {
assertEquals(strVal, rs.getObject(1, String.class));
assertEquals(strVal, rs.getObject("C", String.class));
+ expectSqlConversionError(() -> rs.getObject(1, Date.class),
"date");
+ expectSqlConversionError(() -> rs.getObject("C", Date.class),
"date");
+
+ expectSqlConversionError(() -> rs.getObject(1, Time.class),
"time");
+ expectSqlConversionError(() -> rs.getObject("C", Time.class),
"time");
+
+ expectSqlConversionError(() -> rs.getObject(1, Timestamp.class),
"timestamp");
+ expectSqlConversionError(() -> rs.getObject("C", Timestamp.class),
"timestamp");
+
expectSqlConversionError(() -> rs.getObject(1, UUID.class),
"java.util.UUID");
expectSqlConversionError(() -> rs.getObject("C", UUID.class),
"java.util.UUID");
}
@@ -1444,6 +1642,24 @@ public abstract class JdbcResultSetBaseSelfTest extends
BaseIgniteAbstractTest {
assertEquals(value, rs.getBigDecimal(1));
assertEquals(value, rs.getBigDecimal("C"));
+ expectSqlConversionError(() -> rs.getDate(1), "date");
+ expectSqlConversionError(() -> rs.getDate("C"), "date");
+
+ expectSqlConversionError(() -> rs.getTime(1), "time");
+ expectSqlConversionError(() -> rs.getTime("C"), "time");
+
+ expectSqlConversionError(() -> rs.getTimestamp(1), "timestamp");
+ expectSqlConversionError(() -> rs.getTimestamp("C"), "timestamp");
+
+ expectSqlConversionError(() -> rs.getDate(1,
Calendar.getInstance()), "date");
+ expectSqlConversionError(() -> rs.getDate("C",
Calendar.getInstance()), "date");
+
+ expectSqlConversionError(() -> rs.getTime(1,
Calendar.getInstance()), "time");
+ expectSqlConversionError(() -> rs.getTime("C",
Calendar.getInstance()), "time");
+
+ expectSqlConversionError(() -> rs.getTimestamp(1,
Calendar.getInstance()), "timestamp");
+ expectSqlConversionError(() -> rs.getTimestamp("C",
Calendar.getInstance()), "timestamp");
+
//noinspection deprecation
assertEquals(decimalScaledVal, rs.getBigDecimal(1, 2));
//noinspection deprecation
@@ -1455,6 +1671,23 @@ public abstract class JdbcResultSetBaseSelfTest extends
BaseIgniteAbstractTest {
assertEquals(strVal, rs.getNString(1));
assertEquals(strVal, rs.getNString("C"));
+ expectSqlConversionError(() -> rs.getDate(1), "date");
+ expectSqlConversionError(() -> rs.getDate("C"), "date");
+
+ expectSqlConversionError(() -> rs.getTime(1), "time");
+ expectSqlConversionError(() -> rs.getTime("C"), "time");
+
+ expectSqlConversionError(() -> rs.getTimestamp(1), "timestamp");
+ expectSqlConversionError(() -> rs.getTimestamp("C"), "timestamp");
+
+ expectSqlConversionError(() -> rs.getDate(1,
Calendar.getInstance()), "date");
+ expectSqlConversionError(() -> rs.getDate("C",
Calendar.getInstance()), "date");
+
+ expectSqlConversionError(() -> rs.getTime(1,
Calendar.getInstance()), "time");
+ expectSqlConversionError(() -> rs.getTime("C",
Calendar.getInstance()), "time");
+
+ expectSqlConversionError(() -> rs.getTimestamp(1,
Calendar.getInstance()), "timestamp");
+
// getObject
assertEquals(value, rs.getObject(1));
@@ -1484,6 +1717,15 @@ public abstract class JdbcResultSetBaseSelfTest extends
BaseIgniteAbstractTest {
assertEquals(strVal, rs.getObject(1, String.class));
assertEquals(strVal, rs.getObject("C", String.class));
+ expectSqlConversionError(() -> rs.getObject(1, Date.class),
"date");
+ expectSqlConversionError(() -> rs.getObject("C", Date.class),
"date");
+
+ expectSqlConversionError(() -> rs.getObject(1, Time.class),
"time");
+ expectSqlConversionError(() -> rs.getObject("C", Time.class),
"time");
+
+ expectSqlConversionError(() -> rs.getObject(1, Timestamp.class),
"timestamp");
+ expectSqlConversionError(() -> rs.getObject("C", Timestamp.class),
"timestamp");
+
expectSqlConversionError(() -> rs.getObject(1, UUID.class),
"java.util.UUID");
expectSqlConversionError(() -> rs.getObject("C", UUID.class),
"java.util.UUID");
}
@@ -1718,6 +1960,714 @@ public abstract class JdbcResultSetBaseSelfTest extends
BaseIgniteAbstractTest {
}
}
+ @ParameterizedTest
+ @ValueSource(strings = {"", "abc"})
+ public void getString(String value) throws SQLException {
+ try (ResultSet rs = createSingleRow(new ColumnDefinition("C",
ColumnType.STRING, 0, 0, false), value)) {
+ assertTrue(rs.next());
+
+ expectSqlConversionError(() -> rs.getBoolean(1), "boolean");
+ expectSqlConversionError(() -> rs.getBoolean("C"), "boolean");
+
+ expectSqlConversionError(() -> rs.getByte(1), "byte");
+ expectSqlConversionError(() -> rs.getByte("C"), "byte");
+
+ expectSqlConversionError(() -> rs.getShort(1), "short");
+ expectSqlConversionError(() -> rs.getShort("C"), "short");
+
+ expectSqlConversionError(() -> rs.getInt(1), "int");
+ expectSqlConversionError(() -> rs.getInt("C"), "int");
+
+ expectSqlConversionError(() -> rs.getLong(1), "long");
+ expectSqlConversionError(() -> rs.getLong("C"), "long");
+
+ expectSqlConversionError(() -> rs.getFloat(1), "float");
+ expectSqlConversionError(() -> rs.getFloat("C"), "float");
+
+ expectSqlConversionError(() -> rs.getDouble(1), "double");
+ expectSqlConversionError(() -> rs.getDouble("C"), "double");
+
+ expectSqlConversionError(() -> rs.getBigDecimal(1), "BigDecimal");
+ expectSqlConversionError(() -> rs.getBigDecimal("C"),
"BigDecimal");
+
+ //noinspection deprecation
+ expectSqlConversionError(() -> rs.getBigDecimal(1, 2),
"BigDecimal");
+ //noinspection deprecation
+ expectSqlConversionError(() -> rs.getBigDecimal("C", 4),
"BigDecimal");
+
+ assertEquals(value, rs.getString(1));
+ assertEquals(value, rs.getString("C"));
+
+ assertEquals(value, rs.getNString(1));
+ assertEquals(value, rs.getNString("C"));
+
+ expectSqlConversionError(() -> rs.getDate(1), "date");
+ expectSqlConversionError(() -> rs.getDate("C"), "date");
+
+ expectSqlConversionError(() -> rs.getTime(1), "time");
+ expectSqlConversionError(() -> rs.getTime("C"), "time");
+
+ expectSqlConversionError(() -> rs.getTimestamp(1), "timestamp");
+ expectSqlConversionError(() -> rs.getTimestamp("C"), "timestamp");
+
+ expectSqlConversionError(() -> rs.getDate(1,
Calendar.getInstance()), "date");
+ expectSqlConversionError(() -> rs.getDate("C",
Calendar.getInstance()), "date");
+
+ expectSqlConversionError(() -> rs.getTime(1,
Calendar.getInstance()), "time");
+ expectSqlConversionError(() -> rs.getTime("C",
Calendar.getInstance()), "time");
+
+ expectSqlConversionError(() -> rs.getTimestamp(1,
Calendar.getInstance()), "timestamp");
+ expectSqlConversionError(() -> rs.getTimestamp("C",
Calendar.getInstance()), "timestamp");
+
+ // getObject
+
+ assertEquals(value, rs.getObject(1));
+ assertEquals(value, rs.getObject("C"));
+
+ expectSqlConversionError(() -> rs.getObject(1, Boolean.class),
"boolean");
+ expectSqlConversionError(() -> rs.getObject("C", Boolean.class),
"boolean");
+
+ expectSqlConversionError(() -> rs.getObject(1, Byte.class),
"byte");
+ expectSqlConversionError(() -> rs.getObject("C", Byte.class),
"byte");
+
+ expectSqlConversionError(() -> rs.getObject(1, Short.class),
"short");
+ expectSqlConversionError(() -> rs.getObject("C", Short.class),
"short");
+
+ expectSqlConversionError(() -> rs.getObject(1, Integer.class),
"int");
+ expectSqlConversionError(() -> rs.getObject("C", Integer.class),
"int");
+
+ expectSqlConversionError(() -> rs.getObject(1, Long.class),
"long");
+ expectSqlConversionError(() -> rs.getObject("C", Long.class),
"long");
+
+ expectSqlConversionError(() -> rs.getObject(1, BigDecimal.class),
"BigDecimal");
+ expectSqlConversionError(() -> rs.getObject("C",
BigDecimal.class), "BigDecimal");
+
+ assertEquals(value, rs.getObject(1, String.class));
+ assertEquals(value, rs.getObject("C", String.class));
+
+ expectSqlConversionError(() -> rs.getObject(1, Date.class),
"date");
+ expectSqlConversionError(() -> rs.getObject("C", Date.class),
"date");
+
+ expectSqlConversionError(() -> rs.getObject(1, Time.class),
"time");
+ expectSqlConversionError(() -> rs.getObject("C", Time.class),
"time");
+
+ expectSqlConversionError(() -> rs.getObject(1, Timestamp.class),
"timestamp");
+ expectSqlConversionError(() -> rs.getObject("C", Timestamp.class),
"timestamp");
+ }
+ }
+
+ @ParameterizedTest
+ @MethodSource("getDateValues")
+ public void getDate(LocalDate value) throws SQLException {
+ try (ResultSet rs = createSingleRow(new ColumnDefinition("C",
ColumnType.DATE, 0, 0, false), value)) {
+ assertTrue(rs.next());
+
+ String strVal = value.format(DateTimeFormatter.ISO_DATE);
+
+ expectSqlConversionError(() -> rs.getBoolean(1), "boolean");
+ expectSqlConversionError(() -> rs.getBoolean("C"), "boolean");
+
+ expectSqlConversionError(() -> rs.getByte(1), "byte");
+ expectSqlConversionError(() -> rs.getByte("C"), "byte");
+
+ expectSqlConversionError(() -> rs.getShort(1), "short");
+ expectSqlConversionError(() -> rs.getShort("C"), "short");
+
+ expectSqlConversionError(() -> rs.getInt(1), "int");
+ expectSqlConversionError(() -> rs.getInt("C"), "int");
+
+ expectSqlConversionError(() -> rs.getLong(1), "long");
+ expectSqlConversionError(() -> rs.getLong("C"), "long");
+
+ expectSqlConversionError(() -> rs.getFloat(1), "float");
+ expectSqlConversionError(() -> rs.getFloat("C"), "float");
+
+ expectSqlConversionError(() -> rs.getDouble(1), "double");
+ expectSqlConversionError(() -> rs.getDouble("C"), "double");
+
+ expectSqlConversionError(() -> rs.getBigDecimal(1), "BigDecimal");
+ expectSqlConversionError(() -> rs.getBigDecimal("C"),
"BigDecimal");
+
+ //noinspection deprecation
+ expectSqlConversionError(() -> rs.getBigDecimal(1, 2),
"BigDecimal");
+ //noinspection deprecation
+ expectSqlConversionError(() -> rs.getBigDecimal("C", 4),
"BigDecimal");
+
+ assertEquals(strVal, rs.getString(1));
+ assertEquals(strVal, rs.getString("C"));
+
+ assertEquals(strVal, rs.getNString(1));
+ assertEquals(strVal, rs.getNString("C"));
+
+ assertEquals(Date.valueOf(value), rs.getDate(1));
+ assertEquals(Date.valueOf(value), rs.getDate("C"));
+
+ assertEquals(LocalTime.of(0, 0, 0), rs.getTime(1).toLocalTime());
+ assertEquals(LocalTime.of(0, 0, 0), rs.getTime("C").toLocalTime());
+
+ assertEquals(Timestamp.valueOf(LocalDateTime.of(value,
LocalTime.of(0, 0, 0))), rs.getTimestamp(1));
+ assertEquals(Timestamp.valueOf(LocalDateTime.of(value,
LocalTime.of(0, 0, 0))), rs.getTimestamp("C"));
+
+ assertEquals(Date.valueOf(value), rs.getDate(1,
Calendar.getInstance()));
+ assertEquals(Date.valueOf(value), rs.getDate("C",
Calendar.getInstance()));
+
+ assertEquals(LocalTime.of(0, 0, 0), rs.getTime(1,
Calendar.getInstance()).toLocalTime());
+ assertEquals(LocalTime.of(0, 0, 0), rs.getTime("C",
Calendar.getInstance()).toLocalTime());
+
+ assertEquals(Timestamp.valueOf(LocalDateTime.of(value,
LocalTime.of(0, 0, 0))), rs.getTimestamp(1, Calendar.getInstance()));
+ assertEquals(Timestamp.valueOf(LocalDateTime.of(value,
LocalTime.of(0, 0, 0))), rs.getTimestamp("C", Calendar.getInstance()));
+
+ // getObject
+
+ expectSqlConversionError(() -> rs.getObject(1, Boolean.class),
"boolean");
+ expectSqlConversionError(() -> rs.getObject("C", Boolean.class),
"boolean");
+
+ expectSqlConversionError(() -> rs.getObject(1, Byte.class),
"byte");
+ expectSqlConversionError(() -> rs.getObject("C", Byte.class),
"byte");
+
+ expectSqlConversionError(() -> rs.getObject(1, Short.class),
"short");
+ expectSqlConversionError(() -> rs.getObject("C", Short.class),
"short");
+
+ expectSqlConversionError(() -> rs.getObject(1, Integer.class),
"int");
+ expectSqlConversionError(() -> rs.getObject("C", Integer.class),
"int");
+
+ expectSqlConversionError(() -> rs.getObject(1, Long.class),
"long");
+ expectSqlConversionError(() -> rs.getObject("C", Long.class),
"long");
+
+ expectSqlConversionError(() -> rs.getObject(1, BigDecimal.class),
"BigDecimal");
+ expectSqlConversionError(() -> rs.getObject("C",
BigDecimal.class), "BigDecimal");
+
+ assertEquals(Date.valueOf(value), rs.getObject(1, Date.class));
+ assertEquals(Date.valueOf(value), rs.getObject("C", Date.class));
+
+ assertEquals(LocalTime.of(0, 0, 0), rs.getObject(1,
Time.class).toLocalTime());
+ assertEquals(LocalTime.of(0, 0, 0), rs.getObject("C",
Time.class).toLocalTime());
+
+ assertEquals(Timestamp.valueOf(LocalDateTime.of(value,
LocalTime.of(0, 0, 0))), rs.getObject(1, Timestamp.class));
+ assertEquals(Timestamp.valueOf(LocalDateTime.of(value,
LocalTime.of(0, 0, 0))), rs.getObject("C", Timestamp.class));
+
+ expectSqlConversionError(() -> rs.getObject(1, UUID.class),
"java.util.UUID");
+ expectSqlConversionError(() -> rs.getObject("C", UUID.class),
"java.util.UUID");
+ }
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"Europe/Paris", "America/Los_Angeles",
"Asia/Tokyo"})
+ public void getDateFromDateTimeTypes(String zone) throws SQLException {
+ ZoneId zoneId = ZoneId.of(zone);
+
+ Clock clock =
Clock.fixed(Instant.now().truncatedTo(ChronoUnit.SECONDS),
ZoneId.systemDefault());
+ Instant instant = clock.instant();
+ LocalDateTime dateTime = LocalDateTime.now(clock);
+ LocalTime time = LocalTime.now(clock);
+ LocalDate date = LocalDate.now(clock);
+
+ try (ResultSet rs = createMultiRow(
+ zoneId,
+ new ColumnDefinition[]{
+ new ColumnDefinition("C1", ColumnType.TIME, 0, 0,
false),
+ new ColumnDefinition("C2", ColumnType.DATE, 0, 0,
false),
+ new ColumnDefinition("C3", ColumnType.DATETIME, 0, 0,
false),
+ new ColumnDefinition("C4", ColumnType.TIMESTAMP, 0, 0,
false),
+ },
+ new Object[]{time, date, dateTime, instant})) {
+
+ assertTrue(rs.next());
+
+ // from time
+ assertEquals(LocalDate.of(1970, 1, 1),
rs.getDate(1).toLocalDate());
+
+ // from date
+ assertEquals(date, rs.getDate(2).toLocalDate());
+
+ // from datetime
+ assertEquals(dateTime.toLocalDate(), rs.getDate(3).toLocalDate());
+
+ // from timestamp with local timezone
+ Timestamp ts = rs.getTimestamp(4);
+ assertEquals(ts.toLocalDateTime().toLocalDate(),
rs.getDate(4).toLocalDate());
+ }
+ }
+
+ private static Stream<LocalDate> getDateValues() {
+ return Stream.of(
+ LocalDate.of(1, 1, 1),
+ LocalDate.of(1000, 12, 31),
+ LocalDate.of(1900, 1, 1),
+ LocalDate.of(1947, 9, 30),
+ LocalDate.of(2025, 4, 27),
+ LocalDate.of(2120, 7, 31)
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("getDateStringValues")
+ public void getStringFromDate(boolean valid, LocalDate date, String value)
throws SQLException {
+ try (ResultSet rs = createSingleRow(new ColumnDefinition("C",
ColumnType.DATE, 0, 0, false), date)) {
+ assertTrue(rs.next());
+
+ if (valid) {
+ assertEquals(value, rs.getString(1));
+ assertEquals(value, rs.getString("C"));
+
+ assertEquals(value, rs.getObject(1, String.class));
+ assertEquals(value, rs.getObject("C", String.class));
+ } else {
+ expectSqlConversionError(() -> rs.getString(1), "string");
+ expectSqlConversionError(() -> rs.getString("C"), "string");
+
+ expectSqlConversionError(() -> rs.getObject(1, String.class),
"string");
+ expectSqlConversionError(() -> rs.getObject("C",
String.class), "string");
+ }
+ }
+ }
+
+ private static Stream<Arguments> getDateStringValues() {
+ return Stream.of(
+ Arguments.of(true, LocalDate.of(1, 1, 1), "0001-01-01"),
+ Arguments.of(true, LocalDate.of(200, 3, 17), "0200-03-17"),
+ Arguments.of(true, LocalDate.of(1000, 1, 4), "1000-01-04"),
+ Arguments.of(true, LocalDate.of(2000, 12, 31), "2000-12-31"),
+ Arguments.of(true, LocalDate.of(9999, 12, 31), "9999-12-31"),
+ Arguments.of(false, LocalDate.of(10000, 1, 1), null)
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("getTimeValues")
+ public void getTime(LocalTime value) throws SQLException {
+ try (ResultSet rs = createSingleRow(new ColumnDefinition("C",
ColumnType.TIME, 3, 0, false), value)) {
+ assertTrue(rs.next());
+
+ String strVal =
value.format(DateTimeFormatter.ofPattern("HH:mm:ss.SSS"));
+
+ expectSqlConversionError(() -> rs.getBoolean(1), "boolean");
+ expectSqlConversionError(() -> rs.getBoolean("C"), "boolean");
+
+ expectSqlConversionError(() -> rs.getByte(1), "byte");
+ expectSqlConversionError(() -> rs.getByte("C"), "byte");
+
+ expectSqlConversionError(() -> rs.getShort(1), "short");
+ expectSqlConversionError(() -> rs.getShort("C"), "short");
+
+ expectSqlConversionError(() -> rs.getInt(1), "int");
+ expectSqlConversionError(() -> rs.getInt("C"), "int");
+
+ expectSqlConversionError(() -> rs.getLong(1), "long");
+ expectSqlConversionError(() -> rs.getLong("C"), "long");
+
+ expectSqlConversionError(() -> rs.getFloat(1), "float");
+ expectSqlConversionError(() -> rs.getFloat("C"), "float");
+
+ expectSqlConversionError(() -> rs.getDouble(1), "double");
+ expectSqlConversionError(() -> rs.getDouble("C"), "double");
+
+ expectSqlConversionError(() -> rs.getBigDecimal(1), "BigDecimal");
+ expectSqlConversionError(() -> rs.getBigDecimal("C"),
"BigDecimal");
+
+ //noinspection deprecation
+ expectSqlConversionError(() -> rs.getBigDecimal(1, 2),
"BigDecimal");
+ //noinspection deprecation
+ expectSqlConversionError(() -> rs.getBigDecimal("C", 4),
"BigDecimal");
+
+ assertEquals(strVal, rs.getString(1));
+ assertEquals(strVal, rs.getString("C"));
+
+ assertEquals(strVal, rs.getNString(1));
+ assertEquals(strVal, rs.getNString("C"));
+
+ assertEquals(LocalDate.of(1970, 1, 1),
rs.getDate(1).toLocalDate());
+ assertEquals(LocalDate.of(1970, 1, 1),
rs.getDate("C").toLocalDate());
+
+ assertEquals(value.withNano(0), rs.getTime(1).toLocalTime());
+ assertEquals(value.withNano(0), rs.getTime("C").toLocalTime());
+
+ assertEquals(Timestamp.valueOf(LocalDateTime.of(LocalDate.of(1970,
1, 1), value.withNano(0))), rs.getTimestamp(1));
+ assertEquals(Timestamp.valueOf(LocalDateTime.of(LocalDate.of(1970,
1, 1), value.withNano(0))), rs.getTimestamp("C"));
+
+ assertEquals(LocalDate.of(1970, 1, 1), rs.getDate(1,
Calendar.getInstance()).toLocalDate());
+ assertEquals(LocalDate.of(1970, 1, 1), rs.getDate("C",
Calendar.getInstance()).toLocalDate());
+
+ assertEquals(value.withNano(0), rs.getTime(1,
Calendar.getInstance()).toLocalTime());
+ assertEquals(value.withNano(0), rs.getTime("C",
Calendar.getInstance()).toLocalTime());
+
+ assertEquals(Timestamp.valueOf(LocalDateTime.of(LocalDate.of(1970,
1, 1), value.withNano(0))),
+ rs.getTimestamp(1, Calendar.getInstance()));
+ assertEquals(Timestamp.valueOf(LocalDateTime.of(LocalDate.of(1970,
1, 1), value.withNano(0))),
+ rs.getTimestamp("C", Calendar.getInstance()));
+
+ // getObject
+
+ expectSqlConversionError(() -> rs.getObject(1, Boolean.class),
"boolean");
+ expectSqlConversionError(() -> rs.getObject("C", Boolean.class),
"boolean");
+
+ expectSqlConversionError(() -> rs.getObject(1, Byte.class),
"byte");
+ expectSqlConversionError(() -> rs.getObject("C", Byte.class),
"byte");
+
+ expectSqlConversionError(() -> rs.getObject(1, Short.class),
"short");
+ expectSqlConversionError(() -> rs.getObject("C", Short.class),
"short");
+
+ expectSqlConversionError(() -> rs.getObject(1, Integer.class),
"int");
+ expectSqlConversionError(() -> rs.getObject("C", Integer.class),
"int");
+
+ expectSqlConversionError(() -> rs.getObject(1, Long.class),
"long");
+ expectSqlConversionError(() -> rs.getObject("C", Long.class),
"long");
+
+ expectSqlConversionError(() -> rs.getObject(1, BigDecimal.class),
"BigDecimal");
+ expectSqlConversionError(() -> rs.getObject("C",
BigDecimal.class), "BigDecimal");
+
+ assertEquals(LocalDate.of(1970, 1, 1), rs.getObject(1,
Date.class).toLocalDate());
+ assertEquals(LocalDate.of(1970, 1, 1), rs.getObject("C",
Date.class).toLocalDate());
+
+ assertEquals(value.withNano(0), rs.getObject(1,
Time.class).toLocalTime());
+ assertEquals(value.withNano(0), rs.getObject("C",
Time.class).toLocalTime());
+
+ assertEquals(Timestamp.valueOf(LocalDateTime.of(LocalDate.of(1970,
1, 1), value.withNano(0))),
+ rs.getObject(1, Timestamp.class));
+ assertEquals(Timestamp.valueOf(LocalDateTime.of(LocalDate.of(1970,
1, 1), value.withNano(0))),
+ rs.getObject("C", Timestamp.class));
+
+ expectSqlConversionError(() -> rs.getObject(1, UUID.class),
"java.util.UUID");
+ expectSqlConversionError(() -> rs.getObject("C", UUID.class),
"java.util.UUID");
+ }
+ }
+
+ private static Stream<LocalTime> getTimeValues() {
+ return Stream.of(
+ LocalTime.of(0, 1, 12),
+ LocalTime.of(12, 0, 59).with(ChronoField.MILLI_OF_SECOND, 678)
+ );
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"Europe/Paris", "America/Los_Angeles",
"Asia/Tokyo"})
+ public void getTimeWithTimeZone(String zone) throws SQLException {
+ ZoneId zoneId = ZoneId.of(zone);
+
+ Clock clock =
Clock.fixed(Instant.now().truncatedTo(ChronoUnit.SECONDS),
ZoneId.systemDefault());
+ Instant instant = clock.instant();
+ LocalDateTime dateTime = LocalDateTime.now(clock);
+ LocalTime time = LocalTime.now(clock);
+ LocalDate date = LocalDate.now(clock);
+
+ try (ResultSet rs = createMultiRow(
+ zoneId,
+ new ColumnDefinition[]{
+ new ColumnDefinition("C1", ColumnType.TIME, 0, 0,
false),
+ new ColumnDefinition("C2", ColumnType.DATE, 0, 0,
false),
+ new ColumnDefinition("C3", ColumnType.DATETIME, 0, 0,
false),
+ new ColumnDefinition("C4", ColumnType.TIMESTAMP, 0, 0,
false),
+ },
+ new Object[]{time, date, dateTime, instant})) {
+
+ assertTrue(rs.next());
+
+ // from time
+ assertEquals(time, rs.getTime(1).toLocalTime());
+
+ // from date
+ assertEquals(LocalTime.of(0, 0, 0), rs.getTime(2).toLocalTime());
+
+ // from datetime
+ assertEquals(dateTime.toLocalTime(), rs.getTime(3).toLocalTime());
+
+ // from instant / timestamp ltz
+ Timestamp ts = rs.getTimestamp(4);
+ assertEquals(ts.toLocalDateTime().toLocalTime(),
rs.getTime(4).toLocalTime());
+ }
+ }
+
+ @ParameterizedTest
+ @MethodSource("getTimeStringValues")
+ public void getStringFromTimeWithPrecision(LocalTime time, int precision,
String value) throws SQLException {
+ try (ResultSet rs = createSingleRow(new ColumnDefinition("C",
ColumnType.TIME, precision, 0, false), time)) {
+ assertTrue(rs.next());
+
+ assertEquals(value, rs.getString(1));
+ assertEquals(value, rs.getString("C"));
+
+ assertEquals(value, rs.getObject(1, String.class));
+ assertEquals(value, rs.getObject("C", String.class));
+ }
+ }
+
+ private static Stream<Arguments> getTimeStringValues() {
+ return Stream.of(
+ Arguments.of(LocalTime.of(0, 0, 0, 0), 0, "00:00:00"),
+ Arguments.of(LocalTime.of(0, 0, 0, 0), 1, "00:00:00.0"),
+ Arguments.of(LocalTime.of(0, 0, 0, 0), 2, "00:00:00.00"),
+ Arguments.of(LocalTime.of(0, 0, 0, 0), 3, "00:00:00.000"),
+ Arguments.of(LocalTime.of(0, 0, 0, 0), 6, "00:00:00.000000"),
+ Arguments.of(LocalTime.of(0, 0, 0, 0), 9,
"00:00:00.000000000"),
+
+ Arguments.of(LocalTime.of(13, 5, 2, 123_456), 0, "13:05:02"),
+ Arguments.of(LocalTime.of(13, 5, 2, 123_456), 1, "13:05:02.0"),
+ Arguments.of(LocalTime.of(13, 5, 2, 123_456), 2,
"13:05:02.00"),
+ Arguments.of(LocalTime.of(13, 5, 2, 123_456), 3,
"13:05:02.000"),
+ Arguments.of(LocalTime.of(13, 5, 2, 123_456), 5,
"13:05:02.00012"),
+ Arguments.of(LocalTime.of(13, 5, 2, 123_456), 6,
"13:05:02.000123"),
+ Arguments.of(LocalTime.of(13, 5, 2, 123_456), 9,
"13:05:02.000123456"),
+
+ Arguments.of(LocalTime.of(13, 5, 2, 12345600), 0, "13:05:02"),
+ Arguments.of(LocalTime.of(13, 5, 2, 12345600), 1,
"13:05:02.0"),
+ Arguments.of(LocalTime.of(13, 5, 2, 12345600), 2,
"13:05:02.01"),
+ Arguments.of(LocalTime.of(13, 5, 2, 12345600), 3,
"13:05:02.012"),
+ Arguments.of(LocalTime.of(13, 5, 2, 12345600), 5,
"13:05:02.01234"),
+ Arguments.of(LocalTime.of(13, 5, 2, 12345600), 6,
"13:05:02.012345"),
+ Arguments.of(LocalTime.of(13, 5, 2, 12345600), 9,
"13:05:02.012345600"),
+
+ Arguments.of(LocalTime.of(13, 5, 2, 123_000_000), 0,
"13:05:02"),
+ Arguments.of(LocalTime.of(13, 5, 2, 123_000_000), 1,
"13:05:02.1"),
+ Arguments.of(LocalTime.of(13, 5, 2, 123_000_000), 2,
"13:05:02.12"),
+ Arguments.of(LocalTime.of(13, 5, 2, 123_000_000), 3,
"13:05:02.123"),
+ Arguments.of(LocalTime.of(13, 5, 2, 123_000_000), 6,
"13:05:02.123000"),
+ Arguments.of(LocalTime.of(13, 5, 2, 123_000_000), 9,
"13:05:02.123000000"),
+
+ Arguments.of(LocalTime.of(13, 5, 2, 123456789), 0, "13:05:02"),
+ Arguments.of(LocalTime.of(13, 5, 2, 123456789), 1,
"13:05:02.1"),
+ Arguments.of(LocalTime.of(13, 5, 2, 123456789), 2,
"13:05:02.12"),
+ Arguments.of(LocalTime.of(13, 5, 2, 123456789), 3,
"13:05:02.123"),
+ Arguments.of(LocalTime.of(13, 5, 2, 123456789), 6,
"13:05:02.123456"),
+ Arguments.of(LocalTime.of(13, 5, 2, 123456789), 9,
"13:05:02.123456789")
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("getTimestampValues")
+ public void getTimestamp(Instant value) throws SQLException {
+ ZoneId zoneId = ZoneId.of("UTC");
+
+ try (ResultSet rs = createResultSet(
+ zoneId,
+ List.of(new ColumnDefinition("C", ColumnType.TIMESTAMP, 3, 0,
false)),
+ List.of(List.of(value)))
+ ) {
+ assertTrue(rs.next());
+
+ DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
+ String strVal = LocalDateTime.ofInstant(value,
zoneId).format(formatter);
+
+ expectSqlConversionError(() -> rs.getBoolean(1), "boolean");
+ expectSqlConversionError(() -> rs.getBoolean("C"), "boolean");
+
+ expectSqlConversionError(() -> rs.getByte(1), "byte");
+ expectSqlConversionError(() -> rs.getByte("C"), "byte");
+
+ expectSqlConversionError(() -> rs.getShort(1), "short");
+ expectSqlConversionError(() -> rs.getShort("C"), "short");
+
+ expectSqlConversionError(() -> rs.getInt(1), "int");
+ expectSqlConversionError(() -> rs.getInt("C"), "int");
+
+ expectSqlConversionError(() -> rs.getLong(1), "long");
+ expectSqlConversionError(() -> rs.getLong("C"), "long");
+
+ expectSqlConversionError(() -> rs.getFloat(1), "float");
+ expectSqlConversionError(() -> rs.getFloat("C"), "float");
+
+ expectSqlConversionError(() -> rs.getDouble(1), "double");
+ expectSqlConversionError(() -> rs.getDouble("C"), "double");
+
+ expectSqlConversionError(() -> rs.getBigDecimal(1), "BigDecimal");
+ expectSqlConversionError(() -> rs.getBigDecimal("C"),
"BigDecimal");
+
+ //noinspection deprecation
+ expectSqlConversionError(() -> rs.getBigDecimal(1, 2),
"BigDecimal");
+ //noinspection deprecation
+ expectSqlConversionError(() -> rs.getBigDecimal("C", 4),
"BigDecimal");
+
+ assertEquals(strVal, rs.getString(1));
+ assertEquals(strVal, rs.getString("C"));
+
+ assertEquals(strVal, rs.getNString(1));
+ assertEquals(strVal, rs.getNString("C"));
+
+ LocalDate date = LocalDate.ofInstant(value, zoneId);
+ assertEquals(date, rs.getDate(1).toLocalDate());
+ assertEquals(date, rs.getDate("C").toLocalDate());
+
+ LocalTime time = LocalTime.ofInstant(value, zoneId);
+ assertEquals(time.withNano(0), rs.getTime(1).toLocalTime());
+ assertEquals(time.withNano(0), rs.getTime("C").toLocalTime());
+
+ Timestamp ts = Timestamp.valueOf(LocalDateTime.ofInstant(value,
zoneId));
+ assertEquals(ts, rs.getTimestamp(1));
+ assertEquals(ts, rs.getTimestamp("C"));
+
+ assertEquals(date, rs.getDate(1,
Calendar.getInstance()).toLocalDate());
+ assertEquals(date, rs.getDate("C",
Calendar.getInstance()).toLocalDate());
+
+ assertEquals(time.withNano(0), rs.getTime(1,
Calendar.getInstance()).toLocalTime());
+ assertEquals(time.withNano(0), rs.getTime("C",
Calendar.getInstance()).toLocalTime());
+
+ assertEquals(ts, rs.getTimestamp(1, Calendar.getInstance()));
+ assertEquals(ts, rs.getTimestamp("C", Calendar.getInstance()));
+
+ // getObject
+
+ expectSqlConversionError(() -> rs.getObject(1, Boolean.class),
"boolean");
+ expectSqlConversionError(() -> rs.getObject("C", Boolean.class),
"boolean");
+
+ expectSqlConversionError(() -> rs.getObject(1, Byte.class),
"byte");
+ expectSqlConversionError(() -> rs.getObject("C", Byte.class),
"byte");
+
+ expectSqlConversionError(() -> rs.getObject(1, Short.class),
"short");
+ expectSqlConversionError(() -> rs.getObject("C", Short.class),
"short");
+
+ expectSqlConversionError(() -> rs.getObject(1, Integer.class),
"int");
+ expectSqlConversionError(() -> rs.getObject("C", Integer.class),
"int");
+
+ expectSqlConversionError(() -> rs.getObject(1, Long.class),
"long");
+ expectSqlConversionError(() -> rs.getObject("C", Long.class),
"long");
+
+ expectSqlConversionError(() -> rs.getObject(1, BigDecimal.class),
"BigDecimal");
+ expectSqlConversionError(() -> rs.getObject("C",
BigDecimal.class), "BigDecimal");
+
+ assertEquals(date, rs.getObject(1, Date.class).toLocalDate());
+ assertEquals(date, rs.getObject("C", Date.class).toLocalDate());
+
+ assertEquals(time.withNano(0), rs.getObject(1,
Time.class).toLocalTime());
+ assertEquals(time.withNano(0), rs.getObject("C",
Time.class).toLocalTime());
+
+ assertEquals(ts, rs.getObject(1, Timestamp.class));
+ assertEquals(ts, rs.getObject("C", Timestamp.class));
+
+ expectSqlConversionError(() -> rs.getObject(1, UUID.class),
"java.util.UUID");
+ expectSqlConversionError(() -> rs.getObject("C", UUID.class),
"java.util.UUID");
+ }
+ }
+
+ private static Stream<Instant> getTimestampValues() {
+ return Stream.of(
+ LocalDateTime.of(LocalDate.of(1, 1, 1), LocalTime.of(0, 0, 0)),
+ LocalDateTime.of(LocalDate.of(1000, 12, 31), LocalTime.of(23,
59, 59)),
+ LocalDateTime.of(LocalDate.of(1900, 1, 1), LocalTime.of(0, 0,
0)),
+ LocalDateTime.of(LocalDate.of(1947, 2, 26), LocalTime.of(12,
0, 59).with(ChronoField.MILLI_OF_SECOND, 678)),
+ LocalDateTime.of(LocalDate.of(1947, 2, 26), LocalTime.of(23,
59, 59).with(ChronoField.MILLI_OF_SECOND, 999)),
+ LocalDateTime.of(LocalDate.of(2000, 1, 1), LocalTime.of(0, 0,
0)),
+ LocalDateTime.of(LocalDate.of(2024, 8, 31), LocalTime.of(0, 1,
12)),
+ LocalDateTime.of(LocalDate.of(2124, 12, 31), LocalTime.of(23,
1, 12))
+ ).map(dt -> dt.toInstant(ZoneOffset.UTC));
+ }
+
+ @ParameterizedTest
+ @MethodSource("getStringDateTimeValues")
+ public void getStringFromDateTimeWithPrecision(LocalDateTime time, int
precision, String value) throws SQLException {
+ try (ResultSet rs = createSingleRow(new ColumnDefinition("C",
ColumnType.DATETIME, precision, 0, false), time)) {
+ assertTrue(rs.next());
+
+ assertEquals(value, rs.getString(1));
+ assertEquals(value, rs.getString("C"));
+
+ assertEquals(value, rs.getObject(1, String.class));
+ assertEquals(value, rs.getObject("C", String.class));
+ }
+ }
+
+ private static Stream<Arguments> getStringDateTimeValues() {
+ LocalTime time = LocalTime.of(13, 5, 2, 12345600);
+
+ LocalDate date2 = LocalDate.of(2, 5, 17);
+ LocalDate date20 = LocalDate.of(20, 5, 17);
+ LocalDate date200 = LocalDate.of(200, 5, 17);
+ LocalDate date2000 = LocalDate.of(2000, 5, 17);
+
+ return Stream.of(
+ // 2
+ Arguments.of(LocalDateTime.of(date2, time), 0, "0002-05-17
13:05:02"),
+ Arguments.of(LocalDateTime.of(date2, time), 1, "0002-05-17
13:05:02.0"),
+ Arguments.of(LocalDateTime.of(date2, time), 2, "0002-05-17
13:05:02.01"),
+ Arguments.of(LocalDateTime.of(date2, time), 3, "0002-05-17
13:05:02.012"),
+ Arguments.of(LocalDateTime.of(date2, time), 5, "0002-05-17
13:05:02.01234"),
+ Arguments.of(LocalDateTime.of(date2, time), 6, "0002-05-17
13:05:02.012345"),
+ Arguments.of(LocalDateTime.of(date2, time), 9, "0002-05-17
13:05:02.012345600"),
+
+ // 20
+ Arguments.of(LocalDateTime.of(date20, time), 0, "0020-05-17
13:05:02"),
+ Arguments.of(LocalDateTime.of(date20, time), 1, "0020-05-17
13:05:02.0"),
+ Arguments.of(LocalDateTime.of(date20, time), 2, "0020-05-17
13:05:02.01"),
+ Arguments.of(LocalDateTime.of(date20, time), 3, "0020-05-17
13:05:02.012"),
+ Arguments.of(LocalDateTime.of(date20, time), 5, "0020-05-17
13:05:02.01234"),
+ Arguments.of(LocalDateTime.of(date20, time), 6, "0020-05-17
13:05:02.012345"),
+ Arguments.of(LocalDateTime.of(date20, time), 9, "0020-05-17
13:05:02.012345600"),
+
+ // 200
+ Arguments.of(LocalDateTime.of(date200, time), 0, "0200-05-17
13:05:02"),
+ Arguments.of(LocalDateTime.of(date200, time), 1, "0200-05-17
13:05:02.0"),
+ Arguments.of(LocalDateTime.of(date200, time), 2, "0200-05-17
13:05:02.01"),
+ Arguments.of(LocalDateTime.of(date200, time), 3, "0200-05-17
13:05:02.012"),
+ Arguments.of(LocalDateTime.of(date200, time), 5, "0200-05-17
13:05:02.01234"),
+ Arguments.of(LocalDateTime.of(date200, time), 6, "0200-05-17
13:05:02.012345"),
+ Arguments.of(LocalDateTime.of(date200, time), 9, "0200-05-17
13:05:02.012345600"),
+
+ // 2000
+ Arguments.of(LocalDateTime.of(date2000, time), 0, "2000-05-17
13:05:02"),
+ Arguments.of(LocalDateTime.of(date2000, time), 1, "2000-05-17
13:05:02.0"),
+ Arguments.of(LocalDateTime.of(date2000, time), 2, "2000-05-17
13:05:02.01"),
+ Arguments.of(LocalDateTime.of(date2000, time), 3, "2000-05-17
13:05:02.012"),
+ Arguments.of(LocalDateTime.of(date2000, time), 5, "2000-05-17
13:05:02.01234"),
+ Arguments.of(LocalDateTime.of(date2000, time), 6, "2000-05-17
13:05:02.012345"),
+ Arguments.of(LocalDateTime.of(date2000, time), 9, "2000-05-17
13:05:02.012345600")
+ );
+ }
+
+ @ParameterizedTest
+ @MethodSource("getStringDateTimeValues")
+ public void getStringFromTimestampWithPrecision(LocalDateTime dateTime,
int precision, String value) throws SQLException {
+ ZoneOffset zoneOffset = ZoneOffset.ofHoursMinutes(3, 30);
+ Instant instant = dateTime.toInstant(zoneOffset);
+
+ try (ResultSet rs = createResultSet(zoneOffset,
+ List.of(new ColumnDefinition("C", ColumnType.TIMESTAMP,
precision, 0, false)),
+ List.of(List.of(instant))
+ )) {
+ assertTrue(rs.next());
+
+ assertEquals(value, rs.getString(1));
+ assertEquals(value, rs.getString("C"));
+
+ assertEquals(value, rs.getObject(1, String.class));
+ assertEquals(value, rs.getObject("C", String.class));
+ }
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"Europe/Paris", "America/Los_Angeles",
"Asia/Tokyo"})
+ public void getTimestampWithTimeZone(String zone) throws SQLException {
+ ZoneId zoneId = ZoneId.of(zone);
+
+ Clock clock =
Clock.fixed(Instant.now().truncatedTo(ChronoUnit.SECONDS),
ZoneId.systemDefault());
+ Instant instant = clock.instant();
+ LocalDateTime dateTime = LocalDateTime.now(clock);
+ LocalTime time = LocalTime.now(clock);
+ LocalDate date = LocalDate.now(clock);
+
+ try (ResultSet rs = createMultiRow(
+ zoneId,
+ new ColumnDefinition[]{
+ new ColumnDefinition("C1", ColumnType.TIME, 0, 0,
false),
+ new ColumnDefinition("C2", ColumnType.DATE, 0, 0,
false),
+ new ColumnDefinition("C3", ColumnType.DATETIME, 0, 0,
false),
+ new ColumnDefinition("C4", ColumnType.TIMESTAMP, 0, 0,
false),
+ },
+ new Object[]{time, date, dateTime, instant})) {
+
+ assertTrue(rs.next());
+
+ // from time
+ assertEquals(LocalDateTime.of(LocalDate.of(1970, 1, 1), time),
rs.getTimestamp(1).toLocalDateTime());
+
+ // from date
+ assertEquals(LocalDateTime.of(date, LocalTime.of(0, 0, 0)),
rs.getTimestamp(2).toLocalDateTime());
+
+ // from datetime
+ assertEquals(dateTime, rs.getTimestamp(3).toLocalDateTime());
+
+ // from instant / timestamp ltz
+ assertEquals(LocalDateTime.ofInstant(instant, zoneId),
rs.getTimestamp(4).toLocalDateTime());
+ }
+ }
+
@Test
public void getNotSupportedTypes() throws SQLException {
try (ResultSet rs = createSingleRow(new ColumnDefinition("C",
ColumnType.STRING, 3, 0, false), "ABC")) {
diff --git
a/modules/jdbc/src/test/java/org/apache/ignite/internal/jdbc2/JdbcResultSet2SelfTest.java
b/modules/jdbc/src/test/java/org/apache/ignite/internal/jdbc2/JdbcResultSet2SelfTest.java
index 45014c3b8ba..182bf1e8c22 100644
---
a/modules/jdbc/src/test/java/org/apache/ignite/internal/jdbc2/JdbcResultSet2SelfTest.java
+++
b/modules/jdbc/src/test/java/org/apache/ignite/internal/jdbc2/JdbcResultSet2SelfTest.java
@@ -50,6 +50,7 @@ import java.util.Locale;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.UUID;
+import java.util.function.Supplier;
import org.apache.ignite.internal.jdbc.ColumnDefinition;
import org.apache.ignite.internal.jdbc.JdbcResultSetBaseSelfTest;
import org.apache.ignite.internal.sql.ColumnMetadataImpl;
@@ -74,7 +75,7 @@ import org.mockito.internal.stubbing.answers.ThrowsException;
*/
public class JdbcResultSet2SelfTest extends JdbcResultSetBaseSelfTest {
- // TODO https://issues.apache.org/jira/browse/IGNITE-26379: datetime
+ // getBytes is not implemented yet
@Disabled("https://issues.apache.org/jira/browse/IGNITE-26140")
@Override
@ParameterizedTest
@@ -83,7 +84,7 @@ public class JdbcResultSet2SelfTest extends
JdbcResultSetBaseSelfTest {
super.wasNullPositional(columnType);
}
- // TODO https://issues.apache.org/jira/browse/IGNITE-26379: datetime
+ // getBytes is not implemented yet
@Disabled("https://issues.apache.org/jira/browse/IGNITE-26140")
@Override
@ParameterizedTest
@@ -92,9 +93,6 @@ public class JdbcResultSet2SelfTest extends
JdbcResultSetBaseSelfTest {
super.wasNullNamed(columnType);
}
- // getXXX are not implemented yet
- // TODO https://issues.apache.org/jira/browse/IGNITE-26379: datetime
- @Disabled("https://issues.apache.org/jira/browse/IGNITE-26140")
@Test
@Override
public void getUnknownColumn() throws SQLException {
@@ -157,7 +155,7 @@ public class JdbcResultSet2SelfTest extends
JdbcResultSetBaseSelfTest {
RuntimeException cause = new RuntimeException("Some error");
when(igniteRs.hasNext()).thenThrow(cause);
- ResultSet rs = new JdbcResultSet(igniteRs, statement);
+ ResultSet rs = new JdbcResultSet(igniteRs, statement,
ZoneId::systemDefault);
SQLException err = assertThrows(SQLException.class, rs::next);
assertEquals("Some error", err.getMessage());
@@ -175,7 +173,7 @@ public class JdbcResultSet2SelfTest extends
JdbcResultSetBaseSelfTest {
when(igniteRs.hasNext()).thenReturn(true);
when(igniteRs.next()).thenThrow(cause);
- ResultSet rs = new JdbcResultSet(igniteRs, statement);
+ ResultSet rs = new JdbcResultSet(igniteRs, statement,
ZoneId::systemDefault);
SQLException err = assertThrows(SQLException.class, rs::next);
assertEquals("Some error", err.getMessage());
@@ -192,7 +190,7 @@ public class JdbcResultSet2SelfTest extends
JdbcResultSetBaseSelfTest {
org.apache.ignite.sql.ResultSet<SqlRow> igniteRs =
Mockito.mock(org.apache.ignite.sql.ResultSet.class);
when(igniteRs.metadata()).thenReturn(new
ResultSetMetadataImpl(List.of()));
- ResultSet rs = new JdbcResultSet(igniteRs, statement);
+ ResultSet rs = new JdbcResultSet(igniteRs, statement,
ZoneId::systemDefault);
rs.close();
rs.close();
@@ -212,7 +210,7 @@ public class JdbcResultSet2SelfTest extends
JdbcResultSetBaseSelfTest {
RuntimeException cause = new RuntimeException("Some error");
doAnswer(new ThrowsException(cause)).when(igniteRs).close();
- ResultSet rs = new JdbcResultSet(igniteRs, statement);
+ ResultSet rs = new JdbcResultSet(igniteRs, statement,
ZoneId::systemDefault);
SQLException err = assertThrows(SQLException.class, rs::close);
assertEquals("Some error", err.getMessage());
@@ -236,7 +234,7 @@ public class JdbcResultSet2SelfTest extends
JdbcResultSetBaseSelfTest {
RuntimeException cause = new RuntimeException("Corrupted value");
when(row.value(0)).thenThrow(cause);
- JdbcResultSet rs = new JdbcResultSet(igniteRs, statement);
+ JdbcResultSet rs = new JdbcResultSet(igniteRs, statement,
ZoneId::systemDefault);
assertTrue(rs.next());
SQLException err = assertThrows(SQLException.class, () ->
rs.getValue(1));
@@ -261,12 +259,20 @@ public class JdbcResultSet2SelfTest extends
JdbcResultSetBaseSelfTest {
List<List<Object>> rows
) {
+ Supplier<ZoneId> zoneIdSupplier = () -> {
+ if (zoneId != null) {
+ return zoneId;
+ } else {
+ return ZoneId.systemDefault();
+ }
+ };
+
// ResultSet has no metadata
if (cols.isEmpty() && rows.isEmpty()) {
org.apache.ignite.sql.ResultSet<SqlRow> rs =
Mockito.mock(org.apache.ignite.sql.ResultSet.class);
when(rs.metadata()).thenReturn(null);
- return new JdbcResultSet(rs, statement);
+ return new JdbcResultSet(rs, statement, zoneIdSupplier);
}
List<ColumnMetadata> apiCols = new ArrayList<>();
@@ -281,7 +287,7 @@ public class JdbcResultSet2SelfTest extends
JdbcResultSetBaseSelfTest {
ResultSetMetadata apiMeta = new ResultSetMetadataImpl(apiCols);
- return new JdbcResultSet(new ResultSetStub(apiMeta, rows), statement);
+ return new JdbcResultSet(new ResultSetStub(apiMeta, rows), statement,
zoneIdSupplier);
}
private static class ResultSetStub implements
org.apache.ignite.sql.ResultSet<SqlRow> {