From bf4b95753762a8386841e3d64b03513492dc9af7 Mon Sep 17 00:00:00 2001 From: Ivan Chesnov Date: Fri, 14 Feb 2025 13:13:05 +0200 Subject: [PATCH] DX-100503: more changes --- format/Schema.fbs | 2 +- ...rrowFlightJdbcTimeStampVectorAccessor.java | 88 +++++++++++-------- .../ArrowFlightJdbcTimeStampVectorGetter.java | 13 +++ .../arrow/flatbuf/TimestampWithPrecision.java | 70 +++++++-------- .../java/org/apache/arrow/flatbuf/Type.java | 2 +- 5 files changed, 100 insertions(+), 75 deletions(-) diff --git a/format/Schema.fbs b/format/Schema.fbs index 2f4d00133c1fe..430fbaaff3902 100644 --- a/format/Schema.fbs +++ b/format/Schema.fbs @@ -471,8 +471,8 @@ union Type { BinaryView, Utf8View, ListView, - TimestampWithPrecision LargeListView, + TimestampWithPrecision, } /// ---------------------------------------------------------------------- diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/accessor/impl/calendar/ArrowFlightJdbcTimeStampVectorAccessor.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/accessor/impl/calendar/ArrowFlightJdbcTimeStampVectorAccessor.java index debdd0fcb4b65..be07d06f43df1 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/accessor/impl/calendar/ArrowFlightJdbcTimeStampVectorAccessor.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/accessor/impl/calendar/ArrowFlightJdbcTimeStampVectorAccessor.java @@ -46,6 +46,7 @@ public class ArrowFlightJdbcTimeStampVectorAccessor extends ArrowFlightJdbcAcces /** Functional interface used to convert a number (in any time resolution) to LocalDateTime. */ interface LongToLocalDateTime { + LocalDateTime fromLong(long value); } @@ -126,51 +127,68 @@ public Timestamp getTimestamp(Calendar calendar) { } protected static TimeUnit getTimeUnitForVector(TimeStampVector vector) { - ArrowType.Timestamp arrowType = - (ArrowType.Timestamp) vector.getField().getFieldType().getType(); - - switch (arrowType.getUnit()) { - case NANOSECOND: - return TimeUnit.NANOSECONDS; - case MICROSECOND: - return TimeUnit.MICROSECONDS; - case MILLISECOND: - return TimeUnit.MILLISECONDS; - case SECOND: - return TimeUnit.SECONDS; - default: - throw new UnsupportedOperationException("Invalid Arrow time unit"); + + ArrowType type = vector.getField().getFieldType().getType(); + if (type instanceof ArrowType.Timestamp) { + ArrowType.Timestamp arrowType = + (ArrowType.Timestamp) vector.getField().getFieldType().getType(); + + switch (arrowType.getUnit()) { + case NANOSECOND: + return TimeUnit.NANOSECONDS; + case MICROSECOND: + return TimeUnit.MICROSECONDS; + case MILLISECOND: + return TimeUnit.MILLISECONDS; + case SECOND: + return TimeUnit.SECONDS; + default: + throw new UnsupportedOperationException("Invalid Arrow time unit"); + } + } else if (type instanceof ArrowType.TimestampWithPrecision) { + return TimeUnit.NANOSECONDS; + } else { + throw new UnsupportedOperationException("Invalid Arrow timestamp type"); } } protected static LongToLocalDateTime getLongToLocalDateTimeForVector( TimeStampVector vector, TimeZone timeZone) { String timeZoneID = timeZone.getID(); - - ArrowType.Timestamp arrowType = - (ArrowType.Timestamp) vector.getField().getFieldType().getType(); - - switch (arrowType.getUnit()) { - case NANOSECOND: - return nanoseconds -> DateUtility.getLocalDateTimeFromEpochNano(nanoseconds, timeZoneID); - case MICROSECOND: - return microseconds -> DateUtility.getLocalDateTimeFromEpochMicro(microseconds, timeZoneID); - case MILLISECOND: - return milliseconds -> DateUtility.getLocalDateTimeFromEpochMilli(milliseconds, timeZoneID); - case SECOND: - return seconds -> - DateUtility.getLocalDateTimeFromEpochMilli( - TimeUnit.SECONDS.toMillis(seconds), timeZoneID); - default: - throw new UnsupportedOperationException("Invalid Arrow time unit"); + ArrowType arrowType = vector.getField().getFieldType().getType(); + + if (arrowType instanceof ArrowType.TimestampWithPrecision) { + return nanoseconds -> DateUtility.getLocalDateTimeFromEpochNano(nanoseconds, timeZoneID); + } else { + ArrowType.Timestamp timeStamp = + (ArrowType.Timestamp) vector.getField().getFieldType().getType(); + switch (timeStamp.getUnit()) { + case NANOSECOND: + return nanoseconds -> DateUtility.getLocalDateTimeFromEpochNano(nanoseconds, timeZoneID); + case MICROSECOND: + return microseconds -> + DateUtility.getLocalDateTimeFromEpochMicro(microseconds, timeZoneID); + case MILLISECOND: + return milliseconds -> + DateUtility.getLocalDateTimeFromEpochMilli(milliseconds, timeZoneID); + case SECOND: + return seconds -> + DateUtility.getLocalDateTimeFromEpochMilli( + TimeUnit.SECONDS.toMillis(seconds), timeZoneID); + default: + throw new UnsupportedOperationException("Invalid Arrow time unit"); + } } } protected static TimeZone getTimeZoneForVector(TimeStampVector vector) { - ArrowType.Timestamp arrowType = - (ArrowType.Timestamp) vector.getField().getFieldType().getType(); - - String timezoneName = arrowType.getTimezone(); + ArrowType arrowType = vector.getField().getFieldType().getType(); + String timezoneName; + if (arrowType instanceof ArrowType.TimestampWithPrecision) { + timezoneName = ((ArrowType.TimestampWithPrecision) arrowType).getTimezone(); + } else { + timezoneName = ((ArrowType.Timestamp) arrowType).getTimezone(); + } if (timezoneName == null) { return TimeZone.getTimeZone("UTC"); } diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/accessor/impl/calendar/ArrowFlightJdbcTimeStampVectorGetter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/accessor/impl/calendar/ArrowFlightJdbcTimeStampVectorGetter.java index 7fb74f4a7fba4..3851908710562 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/accessor/impl/calendar/ArrowFlightJdbcTimeStampVectorGetter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/accessor/impl/calendar/ArrowFlightJdbcTimeStampVectorGetter.java @@ -25,6 +25,7 @@ import org.apache.arrow.vector.TimeStampSecTZVector; import org.apache.arrow.vector.TimeStampSecVector; import org.apache.arrow.vector.TimeStampVector; +import org.apache.arrow.vector.TimeStampWithPrecisionVector; import org.apache.arrow.vector.holders.NullableTimeStampMicroHolder; import org.apache.arrow.vector.holders.NullableTimeStampMicroTZHolder; import org.apache.arrow.vector.holders.NullableTimeStampMilliHolder; @@ -33,6 +34,7 @@ import org.apache.arrow.vector.holders.NullableTimeStampNanoTZHolder; import org.apache.arrow.vector.holders.NullableTimeStampSecHolder; import org.apache.arrow.vector.holders.NullableTimeStampSecTZHolder; +import org.apache.arrow.vector.holders.NullableTimeStampWithPrecisionHolder; /** Auxiliary class used to unify data access on TimeStampVectors. */ final class ArrowFlightJdbcTimeStampVectorGetter { @@ -73,6 +75,8 @@ static Getter createGetter(TimeStampVector vector) { return createGetter((TimeStampSecVector) vector); } else if (vector instanceof TimeStampSecTZVector) { return createGetter((TimeStampSecTZVector) vector); + } else if (vector instanceof TimeStampWithPrecisionVector) { + return createGetter((TimeStampWithPrecisionVector) vector); } throw new UnsupportedOperationException("Unsupported Timestamp vector type"); @@ -149,4 +153,13 @@ private static Getter createGetter(TimeStampSecTZVector vector) { holder.value = auxHolder.value; }; } + + private static Getter createGetter(TimeStampWithPrecisionVector vector) { + NullableTimeStampWithPrecisionHolder auxHolder = new NullableTimeStampWithPrecisionHolder(); + return (index, holder) -> { + vector.get(index, auxHolder); + holder.isSet = auxHolder.isSet; + holder.value = auxHolder.value; + }; + } } diff --git a/java/format/src/main/java/org/apache/arrow/flatbuf/TimestampWithPrecision.java b/java/format/src/main/java/org/apache/arrow/flatbuf/TimestampWithPrecision.java index aa801b1ffdf35..6494fe05e4743 100644 --- a/java/format/src/main/java/org/apache/arrow/flatbuf/TimestampWithPrecision.java +++ b/java/format/src/main/java/org/apache/arrow/flatbuf/TimestampWithPrecision.java @@ -17,57 +17,50 @@ package org.apache.arrow.flatbuf; import com.google.flatbuffers.BaseVector; +import com.google.flatbuffers.BooleanVector; +import com.google.flatbuffers.ByteVector; import com.google.flatbuffers.Constants; +import com.google.flatbuffers.DoubleVector; import com.google.flatbuffers.FlatBufferBuilder; +import com.google.flatbuffers.FloatVector; +import com.google.flatbuffers.IntVector; +import com.google.flatbuffers.LongVector; +import com.google.flatbuffers.ShortVector; +import com.google.flatbuffers.StringVector; +import com.google.flatbuffers.Struct; import com.google.flatbuffers.Table; +import com.google.flatbuffers.UnionVector; import java.nio.ByteBuffer; import java.nio.ByteOrder; +@SuppressWarnings("unused") public final class TimestampWithPrecision extends Table { public static void ValidateVersion() { Constants.FLATBUFFERS_24_3_25(); } - public static TimestampWithPrecision getRootAsTimestampWithPrecision(ByteBuffer _bb) { - return getRootAsTimestampWithPrecision(_bb, new TimestampWithPrecision()); - } - public static TimestampWithPrecision getRootAsTimestampWithPrecision(ByteBuffer _bb, TimestampWithPrecision obj) { - _bb.order(ByteOrder.LITTLE_ENDIAN); - return obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb); - } - - public TimestampWithPrecision __init(int _i, ByteBuffer _bb) { - this.bb_pos = _i; - this.bb = _bb; - return this; - } + public static TimestampWithPrecision getRootAsTimestampWithPrecision(ByteBuffer _bb) { return getRootAsTimestampWithPrecision(_bb, new TimestampWithPrecision()); } + public static TimestampWithPrecision getRootAsTimestampWithPrecision(ByteBuffer _bb, TimestampWithPrecision obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); } + public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public TimestampWithPrecision __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - - public int precision() { - int o = this.__offset(4); - return o != 0 ? this.bb.getInt(o + this.bb_pos) : 0; - } - public String timezone() { - int o = this.__offset(6); - return o != 0 ? this.__string(o + this.bb_pos) : null; - } - public ByteBuffer timezoneAsByteBuffer() { - return this.__vector_as_bytebuffer(6, 1); - } + + /** + * Total number of decimal digits + */ + public int precision() { int o = __offset(4); return o != 0 ? bb.getInt(o + bb_pos) : 0; } + public String timezone() { int o = __offset(6); return o != 0 ? __string(o + bb_pos) : null; } + public ByteBuffer timezoneAsByteBuffer() { return __vector_as_bytebuffer(6, 1); } public ByteBuffer timezoneInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 6, 1); } - public static int createTimestampWithPrecision(FlatBufferBuilder builder, int precision, int timezone) { + public static int createTimestampWithPrecision(FlatBufferBuilder builder, + int precision, + int timezoneOffset) { builder.startTable(2); - TimestampWithPrecision.addTimezone(builder, timezone); + TimestampWithPrecision.addTimezone(builder, timezoneOffset); TimestampWithPrecision.addPrecision(builder, precision); - return endTimestampWithPrecision(builder); - } - public static void startTimestampWithPrecision(FlatBufferBuilder builder) { - builder.startTable(2); - } - public static void addPrecision(FlatBufferBuilder builder, int precision) { - builder.addInt(0, precision, 0); - } - public static void addTimezone(FlatBufferBuilder builder, int timezoneOffset) { - builder.addOffset(1, timezoneOffset, 0); + return TimestampWithPrecision.endTimestampWithPrecision(builder); } + + public static void startTimestampWithPrecision(FlatBufferBuilder builder) { builder.startTable(2); } + public static void addPrecision(FlatBufferBuilder builder, int precision) { builder.addInt(0, precision, 0); } + public static void addTimezone(FlatBufferBuilder builder, int timezoneOffset) { builder.addOffset(1, timezoneOffset, 0); } public static int endTimestampWithPrecision(FlatBufferBuilder builder) { int o = builder.endTable(); return o; @@ -76,7 +69,8 @@ public static int endTimestampWithPrecision(FlatBufferBuilder builder) { public static final class Vector extends BaseVector { public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; } - public TimestampWithPrecision get(int j) { return get( new TimestampWithPrecision(), j); } + public TimestampWithPrecision get(int j) { return get(new TimestampWithPrecision(), j); } public TimestampWithPrecision get(TimestampWithPrecision obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); } } } + diff --git a/java/format/src/main/java/org/apache/arrow/flatbuf/Type.java b/java/format/src/main/java/org/apache/arrow/flatbuf/Type.java index ef0df978124c4..c032d24ecdf71 100644 --- a/java/format/src/main/java/org/apache/arrow/flatbuf/Type.java +++ b/java/format/src/main/java/org/apache/arrow/flatbuf/Type.java @@ -53,7 +53,7 @@ private Type() { } public static final byte LargeListView = 26; public static final byte TimestampWithPrecision = 27; - public static final String[] names = { "NONE", "Null", "Int", "FloatingPoint", "Binary", "Utf8", "Bool", "Decimal", "Date", "Time", "Timestamp", "Interval", "List", "Struct_", "Union", "FixedSizeBinary", "FixedSizeList", "Map", "Duration", "LargeBinary", "LargeUtf8", "LargeList", "RunEndEncoded", "BinaryView", "Utf8View", "ListView", "LargeListView", "TimestampWithPrecision",}; + public static final String[] names = { "NONE", "Null", "Int", "FloatingPoint", "Binary", "Utf8", "Bool", "Decimal", "Date", "Time", "Timestamp", "Interval", "List", "Struct_", "Union", "FixedSizeBinary", "FixedSizeList", "Map", "Duration", "LargeBinary", "LargeUtf8", "LargeList", "RunEndEncoded", "BinaryView", "Utf8View", "ListView", "LargeListView", "TimestampWithPrecision", }; public static String name(int e) { return names[e]; } }