提交 d0e0e8f9 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Remap Instant to Value.TIMESTAMP_TZ

上级 cecf30f0
...@@ -101,9 +101,13 @@ public class LocalDateTimeUtils { ...@@ -101,9 +101,13 @@ public class LocalDateTimeUtils {
private static final Method LOCAL_DATE_AT_START_OF_DAY; private static final Method LOCAL_DATE_AT_START_OF_DAY;
/** /**
* {@code java.sql.Timestamp.from(java.time.Instant)} or {@code null}. * {@code java.time.Instant#getEpochSecond()} or {@code null}.
*/ */
private static final Method TIMESTAMP_FROM; private static final Method INSTANT_GET_EPOCH_SECOND;
/**
* {@code java.time.Instant#getNano()} or {@code null}.
*/
private static final Method INSTANT_GET_NANO;
/** /**
* {@code java.sql.Timestamp.toInstant()} or {@code null}. * {@code java.sql.Timestamp.toInstant()} or {@code null}.
*/ */
...@@ -186,7 +190,8 @@ public class LocalDateTimeUtils { ...@@ -186,7 +190,8 @@ public class LocalDateTimeUtils {
LOCAL_DATE_GET_DAY_OF_MONTH = getMethod(LOCAL_DATE, "getDayOfMonth"); LOCAL_DATE_GET_DAY_OF_MONTH = getMethod(LOCAL_DATE, "getDayOfMonth");
LOCAL_DATE_AT_START_OF_DAY = getMethod(LOCAL_DATE, "atStartOfDay"); LOCAL_DATE_AT_START_OF_DAY = getMethod(LOCAL_DATE, "atStartOfDay");
TIMESTAMP_FROM = getMethod(Timestamp.class, "from", INSTANT); INSTANT_GET_EPOCH_SECOND = getMethod(INSTANT, "getEpochSecond");
INSTANT_GET_NANO = getMethod(INSTANT, "getNano");
TIMESTAMP_TO_INSTANT = getMethod(Timestamp.class, "toInstant"); TIMESTAMP_TO_INSTANT = getMethod(Timestamp.class, "toInstant");
LOCAL_TIME_PARSE = getMethod(LOCAL_TIME, "parse", CharSequence.class); LOCAL_TIME_PARSE = getMethod(LOCAL_TIME, "parse", CharSequence.class);
...@@ -214,7 +219,8 @@ public class LocalDateTimeUtils { ...@@ -214,7 +219,8 @@ public class LocalDateTimeUtils {
LOCAL_DATE_GET_MONTH_VALUE = null; LOCAL_DATE_GET_MONTH_VALUE = null;
LOCAL_DATE_GET_DAY_OF_MONTH = null; LOCAL_DATE_GET_DAY_OF_MONTH = null;
LOCAL_DATE_AT_START_OF_DAY = null; LOCAL_DATE_AT_START_OF_DAY = null;
TIMESTAMP_FROM = null; INSTANT_GET_EPOCH_SECOND = null;
INSTANT_GET_NANO = null;
TIMESTAMP_TO_INSTANT = null; TIMESTAMP_TO_INSTANT = null;
LOCAL_TIME_PARSE = null; LOCAL_TIME_PARSE = null;
LOCAL_DATE_TIME_PLUS_NANOS = null; LOCAL_DATE_TIME_PLUS_NANOS = null;
...@@ -485,7 +491,16 @@ public class LocalDateTimeUtils { ...@@ -485,7 +491,16 @@ public class LocalDateTimeUtils {
*/ */
public static Value instantToValue(Object instant) { public static Value instantToValue(Object instant) {
try { try {
return ValueTimestamp.get((Timestamp) TIMESTAMP_FROM.invoke(null, instant)); long epochSecond = (long) INSTANT_GET_EPOCH_SECOND.invoke(instant);
int nano = (int) INSTANT_GET_NANO.invoke(instant);
long absoluteDay = epochSecond / 86_400;
// Round toward negative infinity
if (epochSecond < 0 && (absoluteDay * 86_400 != epochSecond)) {
absoluteDay--;
}
long timeNanos = (epochSecond - absoluteDay * 86_400) * 1_000_000_000 + nano;
return ValueTimestampTimeZone.fromDateValueAndNanos(
DateTimeUtils.dateValueFromAbsoluteDay(absoluteDay), timeNanos, (short) 0);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
throw DbException.convert(e); throw DbException.convert(e);
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
......
...@@ -1020,9 +1020,9 @@ public class DataType { ...@@ -1020,9 +1020,9 @@ public class DataType {
return Value.DATE; return Value.DATE;
} else if (LocalDateTimeUtils.LOCAL_TIME == x) { } else if (LocalDateTimeUtils.LOCAL_TIME == x) {
return Value.TIME; return Value.TIME;
} else if (LocalDateTimeUtils.LOCAL_DATE_TIME == x || LocalDateTimeUtils.INSTANT == x) { } else if (LocalDateTimeUtils.LOCAL_DATE_TIME == x) {
return Value.TIMESTAMP; return Value.TIMESTAMP;
} else if (LocalDateTimeUtils.OFFSET_DATE_TIME == x) { } else if (LocalDateTimeUtils.OFFSET_DATE_TIME == x || LocalDateTimeUtils.INSTANT == x) {
return Value.TIMESTAMP_TZ; return Value.TIMESTAMP_TZ;
} else { } else {
if (JdbcUtils.customDataTypesHandler != null) { if (JdbcUtils.customDataTypesHandler != null) {
......
...@@ -9,6 +9,7 @@ import java.io.ByteArrayInputStream; ...@@ -9,6 +9,7 @@ import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.StringReader; import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
...@@ -755,18 +756,26 @@ public class TestPreparedStatement extends TestBase { ...@@ -755,18 +756,26 @@ public class TestPreparedStatement extends TestBase {
if (!LocalDateTimeUtils.isJava8DateApiPresent()) { if (!LocalDateTimeUtils.isJava8DateApiPresent()) {
return; return;
} }
Method timestampToInstant = Timestamp.class.getMethod("toInstant"), Method timestampToInstant = Timestamp.class.getMethod("toInstant");
now = LocalDateTimeUtils.INSTANT.getMethod("now"); Method now = LocalDateTimeUtils.INSTANT.getMethod("now");
Method parse = LocalDateTimeUtils.INSTANT.getMethod("parse", CharSequence.class);
PreparedStatement prep = conn.prepareStatement("SELECT ?"); PreparedStatement prep = conn.prepareStatement("SELECT ?");
Object instant1 = now.invoke(null);
prep.setObject(1, instant1); testInstant8Impl(prep, timestampToInstant, now.invoke(null));
testInstant8Impl(prep, timestampToInstant, parse.invoke(null, "2000-01-15T12:13:14.123456789Z"));
testInstant8Impl(prep, timestampToInstant, parse.invoke(null, "1500-09-10T23:22:11.123456789Z"));
}
private void testInstant8Impl(PreparedStatement prep, Method timestampToInstant, Object instant)
throws SQLException, IllegalAccessException, InvocationTargetException {
prep.setObject(1, instant);
ResultSet rs = prep.executeQuery(); ResultSet rs = prep.executeQuery();
rs.next(); rs.next();
Object instant2 = rs.getObject(1, LocalDateTimeUtils.INSTANT); Object instant2 = rs.getObject(1, LocalDateTimeUtils.INSTANT);
assertEquals(instant1, instant2); assertEquals(instant, instant2);
Timestamp ts = rs.getTimestamp(1); Timestamp ts = rs.getTimestamp(1);
assertEquals(instant1, timestampToInstant.invoke(ts)); assertEquals(instant, timestampToInstant.invoke(ts));
assertFalse(rs.next()); assertFalse(rs.next());
rs.close(); rs.close();
...@@ -774,7 +783,7 @@ public class TestPreparedStatement extends TestBase { ...@@ -774,7 +783,7 @@ public class TestPreparedStatement extends TestBase {
rs = prep.executeQuery(); rs = prep.executeQuery();
rs.next(); rs.next();
instant2 = rs.getObject(1, LocalDateTimeUtils.INSTANT); instant2 = rs.getObject(1, LocalDateTimeUtils.INSTANT);
assertEquals(instant1, instant2); assertEquals(instant, instant2);
assertFalse(rs.next()); assertFalse(rs.next());
rs.close(); rs.close();
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论