From 282b0b717d0cc6bb54c9f8f9d59e8841dd283c82 Mon Sep 17 00:00:00 2001 From: Micah Kornfield Date: Thu, 14 Feb 2019 02:58:19 -0800 Subject: [PATCH] Interval type by augmenting existing interval --- format/Schema.fbs | 7 +- .../src/main/codegen/data/ArrowTypes.tdd | 3 +- .../main/codegen/data/ValueVectorTypes.tdd | 2 + .../src/main/codegen/includes/vv_imports.ftl | 4 + .../templates/AbstractFieldReader.java | 2 +- .../codegen/templates/HolderReaderImpl.java | 2 + .../main/codegen/templates/NullReader.java | 2 +- .../vector/IntervalEpochSecondVector.java | 424 ++++++++++++++++++ .../org/apache/arrow/vector/TypeLayout.java | 3 +- .../arrow/vector/types/IntervalUnit.java | 3 +- .../apache/arrow/vector/types/TimeUnit.java | 3 +- .../org/apache/arrow/vector/types/Types.java | 34 +- .../arrow/vector/types/pojo/TestSchema.java | 10 +- 13 files changed, 482 insertions(+), 17 deletions(-) create mode 100644 java/vector/src/main/java/org/apache/arrow/vector/IntervalEpochSecondVector.java diff --git a/format/Schema.fbs b/format/Schema.fbs index 9e52a8d5f9e..8c0740255cf 100644 --- a/format/Schema.fbs +++ b/format/Schema.fbs @@ -140,7 +140,7 @@ table Date { unit: DateUnit = MILLISECOND; } -enum TimeUnit: short { SECOND, MILLISECOND, MICROSECOND, NANOSECOND } +enum TimeUnit: short { SECOND, MILLISECOND, MICROSECOND, NANOSECOND, NOT_APPLICABLE } /// Time type. The physical storage type depends on the unit /// - SECOND and MILLISECOND: 32 bits @@ -182,9 +182,10 @@ table Timestamp { timezone: string; } -enum IntervalUnit: short { YEAR_MONTH, DAY_TIME} +enum IntervalUnit: short { YEAR_MONTH, DAY_TIME, EPOCH} table Interval { - unit: IntervalUnit; + type: IntervalUnit; + unit: TimeUnit = NOT_APPLICABLE; } /// ---------------------------------------------------------------------- diff --git a/java/vector/src/main/codegen/data/ArrowTypes.tdd b/java/vector/src/main/codegen/data/ArrowTypes.tdd index 0b7eb918231..7d35b9a0aa6 100644 --- a/java/vector/src/main/codegen/data/ArrowTypes.tdd +++ b/java/vector/src/main/codegen/data/ArrowTypes.tdd @@ -92,7 +92,8 @@ }, { name: "Interval", - fields: [{name: "unit", type: short, valueType: IntervalUnit}], + fields: [{name: "type", type: short, valueType: IntervalUnit}, + {name: "unit", type: short, valueType: TimeUnit}], complex: false } ] diff --git a/java/vector/src/main/codegen/data/ValueVectorTypes.tdd b/java/vector/src/main/codegen/data/ValueVectorTypes.tdd index 71eed911cad..cbfaa06ef87 100644 --- a/java/vector/src/main/codegen/data/ValueVectorTypes.tdd +++ b/java/vector/src/main/codegen/data/ValueVectorTypes.tdd @@ -76,6 +76,8 @@ { class: "UInt8" }, { class: "Float8", javaType: "double", boxedType: "Double", fields: [{name: "value", type: "double"}] }, { class: "DateMilli", javaType: "long", friendlyType: "LocalDateTime" }, + { class: "IntervalEpochSecond", javaType: "long", friendlyType: "Duration"} + { class: "TimeStampSec", javaType: "long", boxedType: "Long", friendlyType: "LocalDateTime" }, { class: "TimeStampMilli", javaType: "long", boxedType: "Long", friendlyType: "LocalDateTime" }, { class: "TimeStampMicro", javaType: "long", boxedType: "Long", friendlyType: "LocalDateTime" }, diff --git a/java/vector/src/main/codegen/includes/vv_imports.ftl b/java/vector/src/main/codegen/includes/vv_imports.ftl index 7bd884cfc24..771d19faa7d 100644 --- a/java/vector/src/main/codegen/includes/vv_imports.ftl +++ b/java/vector/src/main/codegen/includes/vv_imports.ftl @@ -55,6 +55,8 @@ import java.sql.Timestamp; import java.math.BigDecimal; import java.math.BigInteger; +import java.time.Duration; + import org.joda.time.DateTime; import org.joda.time.LocalDateTime; import org.joda.time.Period; @@ -64,3 +66,5 @@ import org.joda.time.Period; + + diff --git a/java/vector/src/main/codegen/templates/AbstractFieldReader.java b/java/vector/src/main/codegen/templates/AbstractFieldReader.java index d1d2bdfc117..06f7d2e4a2b 100644 --- a/java/vector/src/main/codegen/templates/AbstractFieldReader.java +++ b/java/vector/src/main/codegen/templates/AbstractFieldReader.java @@ -51,7 +51,7 @@ public Field getField() { <#list ["Object", "BigDecimal", "Integer", "Long", "Boolean", "Character", "LocalDateTime", "Period", "Double", "Float", - "Text", "String", "Byte", "Short", "byte[]"] as friendlyType> + "Text", "String", "Byte", "Short", "byte[]", "Duration"] as friendlyType> <#assign safeType=friendlyType /> <#if safeType=="byte[]"><#assign safeType="ByteArray" /> public ${friendlyType} read${safeType}(int arrayIndex) { diff --git a/java/vector/src/main/codegen/templates/HolderReaderImpl.java b/java/vector/src/main/codegen/templates/HolderReaderImpl.java index 264e8c11f57..b521300ee14 100644 --- a/java/vector/src/main/codegen/templates/HolderReaderImpl.java +++ b/java/vector/src/main/codegen/templates/HolderReaderImpl.java @@ -120,6 +120,8 @@ public void read(Nullable${name}Holder h) { <#elseif minor.class == "IntervalDay"> Period p = new Period(); return p.plusDays(holder.days).plusMillis(holder.milliseconds); + <#elseif minor.class == "IntervalEpochSecond"> + return Duration.ofSeconds(holder.value); <#elseif minor.class == "Bit" > return new Boolean(holder.value != 0); <#elseif minor.class == "Decimal"> diff --git a/java/vector/src/main/codegen/templates/NullReader.java b/java/vector/src/main/codegen/templates/NullReader.java index d4ed6e8cb7f..18cbbd5933b 100644 --- a/java/vector/src/main/codegen/templates/NullReader.java +++ b/java/vector/src/main/codegen/templates/NullReader.java @@ -128,7 +128,7 @@ private void fail(String name){ <#list ["Object", "BigDecimal", "Integer", "Long", "Boolean", "Character", "LocalDateTime", "Period", "Double", "Float", - "Text", "String", "Byte", "Short", "byte[]"] as friendlyType> + "Text", "String", "Byte", "Short", "byte[]", "Duration"] as friendlyType> <#assign safeType=friendlyType /> <#if safeType=="byte[]"><#assign safeType="ByteArray" /> diff --git a/java/vector/src/main/java/org/apache/arrow/vector/IntervalEpochSecondVector.java b/java/vector/src/main/java/org/apache/arrow/vector/IntervalEpochSecondVector.java new file mode 100644 index 00000000000..29523ee3f4c --- /dev/null +++ b/java/vector/src/main/java/org/apache/arrow/vector/IntervalEpochSecondVector.java @@ -0,0 +1,424 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.arrow.vector; + +import java.time.Duration; + +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.vector.complex.impl.IntervalEpochSecondReaderImpl; +import org.apache.arrow.vector.complex.reader.FieldReader; +import org.apache.arrow.vector.holders.IntervalEpochSecondHolder; +import org.apache.arrow.vector.holders.NullableIntervalEpochSecondHolder; +import org.apache.arrow.vector.types.Types.MinorType; +import org.apache.arrow.vector.types.pojo.FieldType; +import org.apache.arrow.vector.util.TransferPair; + +import io.netty.buffer.ArrowBuf; + +/** + * IntervalEpochSecondVector implements a fixed width vector (8 bytes) of + * a second granularity values which could be null. + * A validity buffer (bit vector) is maintained to track which elements in the + * vector are null. + */ +public class IntervalEpochSecondVector extends BaseFixedWidthVector { + private static final byte TYPE_WIDTH = 8; + private final FieldReader reader; + + /** + * Instantiate a IntervalDayVector. This doesn't allocate any memory for + * the data in vector. + * + * @param name name of the vector + * @param allocator allocator for memory management. + */ + public IntervalEpochSecondVector(String name, BufferAllocator allocator) { + this(name, FieldType.nullable(MinorType.INTERVALDAY.getType()), allocator); + } + + /** + * Instantiate a IntervalDayVector. This doesn't allocate any memory for + * the data in vector. + * + * @param name name of the vector + * @param fieldType type of Field materialized by this vector + * @param allocator allocator for memory management. + */ + public IntervalEpochSecondVector(String name, FieldType fieldType, BufferAllocator allocator) { + super(name, allocator, fieldType, TYPE_WIDTH); + reader = new IntervalEpochSecondReaderImpl(IntervalEpochSecondVector.this); + } + + /** + * Get a reader that supports reading values from this vector. + * + * @return Field Reader for this vector + */ + @Override + public FieldReader getReader() { + return reader; + } + + /** + * Get minor type for this vector. The vector holds values belonging + * to a particular type. + * + * @return {@link MinorType} + */ + @Override + public MinorType getMinorType() { + return MinorType.INTERVALEPOCHSECOND; + } + + + /*----------------------------------------------------------------* + | | + | vector value retrieval methods | + | | + *----------------------------------------------------------------*/ + + + /** + * Get the element at the given index from the vector. + * + * @param index position of element + * @return element at given index + */ + public ArrowBuf get(int index) throws IllegalStateException { + if (isSet(index) == 0) { + return null; + } + return valueBuffer.slice(index * TYPE_WIDTH, TYPE_WIDTH); + } + + /** + * Get the element at the given index from the vector and + * sets the state in holder. If element at given index + * is null, holder.isSet will be zero. + * + * @param index position of element + */ + public void get(int index, NullableIntervalEpochSecondHolder holder) { + if (isSet(index) == 0) { + holder.isSet = 0; + return; + } + final int startIndex = index * TYPE_WIDTH; + holder.isSet = 1; + holder.value = valueBuffer.getLong(startIndex ); + } + + /** + * Same as {@link #get(int)}. + * + * @param index position of element + * @return element at given index + */ + public Duration getObject(int index) { + if (isSet(index) == 0) { + return null; + } else { + final long seconds = valueBuffer.getLong(index); + return Duration.ofSeconds(seconds); + } + } + + /** + * Get the Interval value at a given index as a {@link StringBuilder} object. + * + * @param index position of the element + * @return String Builder object with Interval value as + * [days, hours, minutes, seconds, millis] + */ + public StringBuilder getAsStringBuilder(int index) { + if (isSet(index) == 0) { + return null; + } else { + return getAsStringBuilderHelper(index); + } + } + + private StringBuilder getAsStringBuilderHelper(int index) { + final int startIndex = index * TYPE_WIDTH; + + long seconds = valueBuffer.getLong(startIndex); + Duration duration = Duration.ofSeconds(seconds); + + final long days = duration.toDays(); + duration = duration.minusDays(days); + + final long hours = duration.toHours(); + duration = duration.minusHours(hours); + + final long minutes = duration.toMinutes(); + duration = duration.minusMinutes(minutes); + + final String dayString = (Math.abs(days) == 1) ? " day " : " days "; + + return (new StringBuilder() + .append(days).append(dayString) + .append(hours).append(":") + .append(minutes).append(":") + .append(duration.getSeconds())); + } + + /** + * Copy a cell value from a particular index in source vector to a particular + * position in this vector. + * + * @param fromIndex position to copy from in source vector + * @param thisIndex position to copy to in this vector + * @param from source vector + */ + public void copyFrom(int fromIndex, int thisIndex, IntervalEpochSecondVector from) { + BitVectorHelper.setValidityBit(validityBuffer, thisIndex, from.isSet(fromIndex)); + from.valueBuffer.getBytes(fromIndex * TYPE_WIDTH, this.valueBuffer, + thisIndex * TYPE_WIDTH, TYPE_WIDTH); + } + + /** + * Same as {@link #copyFrom(int, int, IntervalEpochSecondVector)} except that + * it handles the case when the capacity of the vector needs to be expanded + * before copy. + * + * @param fromIndex position to copy from in source vector + * @param thisIndex position to copy to in this vector + * @param from source vector + */ + public void copyFromSafe(int fromIndex, int thisIndex, IntervalEpochSecondVector from) { + handleSafe(thisIndex); + copyFrom(fromIndex, thisIndex, from); + } + + + /*----------------------------------------------------------------* + | | + | vector value setter methods | + | | + *----------------------------------------------------------------*/ + + + /** + * Set the element at the given index to the given value. + * + * @param index position of element + * @param value value of element + */ + public void set(int index, ArrowBuf value) { + BitVectorHelper.setValidityBitToOne(validityBuffer, index); + valueBuffer.setBytes(index * TYPE_WIDTH, value, 0, TYPE_WIDTH); + } + + /** + * Set the element at the given index to the given value. + * + * @param index position of element + * @param seconds seconds for the interval + */ + public void set(int index, long seconds) { + final int offsetIndex = index * TYPE_WIDTH; + BitVectorHelper.setValidityBitToOne(validityBuffer, index); + valueBuffer.setLong(offsetIndex, seconds); + } + + /** + * Set the element at the given index to the value set in data holder. + * If the value in holder is not indicated as set, element in the + * at the given index will be null. + * + * @param index position of element + * @param holder nullable data holder for value of element + */ + public void set(int index, NullableIntervalEpochSecondHolder holder) throws IllegalArgumentException { + if (holder.isSet < 0) { + throw new IllegalArgumentException(); + } else if (holder.isSet > 0) { + set(index, holder.value); + } else { + BitVectorHelper.setValidityBit(validityBuffer, index, 0); + } + } + + /** + * Set the element at the given index to the value set in data holder. + * + * @param index position of element + * @param holder data holder for value of element + */ + public void set(int index, IntervalEpochSecondHolder holder) { + set(index, holder.value); + } + + /** + * Same as {@link #set(int, ArrowBuf)} except that it handles the + * case when index is greater than or equal to existing + * value capacity {@link #getValueCapacity()}. + * + * @param index position of element + * @param value value of element + */ + public void setSafe(int index, ArrowBuf value) { + handleSafe(index); + set(index, value); + } + + /** + * Same as {@link #set(int, long)} except that it handles the + * case when index is greater than or equal to existing + * value capacity {@link #getValueCapacity()}. + * + * @param index position of element + * @param seconds seconds for the interval + */ + public void setSafe(int index, long seconds) { + handleSafe(index); + set(index, seconds); + } + + /** + * Same as {@link #set(int, NullableIntervalEpochSecondHolder)} except that it handles the + * case when index is greater than or equal to existing + * value capacity {@link #getValueCapacity()}. + * + * @param index position of element + * @param holder nullable data holder for value of element + */ + public void setSafe(int index, NullableIntervalEpochSecondHolder holder) throws IllegalArgumentException { + handleSafe(index); + set(index, holder); + } + + /** + * Same as {@link #set(int, IntervalEpochSecondHolder)} except that it handles the + * case when index is greater than or equal to existing + * value capacity {@link #getValueCapacity()}. + * + * @param index position of element + * @param holder data holder for value of element + */ + public void setSafe(int index, IntervalEpochSecondHolder holder) { + handleSafe(index); + set(index, holder); + } + + /** + * Set the element at the given index to null. + * + * @param index position of element + */ + public void setNull(int index) { + handleSafe(index); + // not really needed to set the bit to 0 as long as + // the buffer always starts from 0. + BitVectorHelper.setValidityBit(validityBuffer, index, 0); + } + + /** + * Store the given value at a particular position in the vector. isSet indicates + * whether the value is NULL or not. + * + * @param index position of the new value + * @param isSet 0 for NULL value, 1 otherwise + * @param seconds the amount of time in seconds + */ + public void set(int index, int isSet, long seconds) { + if (isSet > 0) { + set(index, seconds); + } else { + BitVectorHelper.setValidityBit(validityBuffer, index, 0); + } + } + + /** + * Same as {@link #set(int, int, long)} except that it handles the case + * when index is greater than or equal to current value capacity of the + * vector. + * + * @param index position of the new value + * @param isSet 0 for NULL value, 1 otherwise + * @param seconds millisecond component of interval + */ + public void setSafe(int index, int isSet, long seconds) { + handleSafe(index); + set(index, isSet, seconds); + } + + + /*----------------------------------------------------------------* + | | + | vector transfer | + | | + *----------------------------------------------------------------*/ + + + /** + * Construct a TransferPair comprising of this and and a target vector of + * the same type. + * + * @param ref name of the target vector + * @param allocator allocator for the target vector + * @return {@link TransferPair} + */ + @Override + public TransferPair getTransferPair(String ref, BufferAllocator allocator) { + return new TransferImpl(ref, allocator); + } + + /** + * Construct a TransferPair with a desired target vector of the same type. + * + * @param to target vector + * @return {@link TransferPair} + */ + @Override + public TransferPair makeTransferPair(ValueVector to) { + return new TransferImpl((IntervalEpochSecondVector) to); + } + + private class TransferImpl implements TransferPair { + IntervalEpochSecondVector to; + + public TransferImpl(String ref, BufferAllocator allocator) { + to = new IntervalEpochSecondVector(ref, field.getFieldType(), allocator); + } + + public TransferImpl(IntervalEpochSecondVector to) { + this.to = to; + } + + @Override + public IntervalEpochSecondVector getTo() { + return to; + } + + @Override + public void transfer() { + transferTo(to); + } + + @Override + public void splitAndTransfer(int startIndex, int length) { + splitAndTransferTo(startIndex, length, to); + } + + @Override + public void copyValueSafe(int fromIndex, int toIndex) { + to.copyFromSafe(fromIndex, toIndex, IntervalEpochSecondVector.this); + } + } +} diff --git a/java/vector/src/main/java/org/apache/arrow/vector/TypeLayout.java b/java/vector/src/main/java/org/apache/arrow/vector/TypeLayout.java index 1a639ce2438..40f5e15716a 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/TypeLayout.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/TypeLayout.java @@ -192,7 +192,8 @@ public TypeLayout visit(Time type) { @Override public TypeLayout visit(Interval type) { - switch (type.getUnit()) { + switch (type.getType()) { + case EPOCH: case DAY_TIME: return newFixedWidthTypeLayout(BufferLayout.dataBuffer(64)); case YEAR_MONTH: diff --git a/java/vector/src/main/java/org/apache/arrow/vector/types/IntervalUnit.java b/java/vector/src/main/java/org/apache/arrow/vector/types/IntervalUnit.java index 68abf4dbabd..a4480a304aa 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/types/IntervalUnit.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/types/IntervalUnit.java @@ -19,7 +19,8 @@ public enum IntervalUnit { YEAR_MONTH(org.apache.arrow.flatbuf.IntervalUnit.YEAR_MONTH), - DAY_TIME(org.apache.arrow.flatbuf.IntervalUnit.DAY_TIME); + DAY_TIME(org.apache.arrow.flatbuf.IntervalUnit.DAY_TIME), + EPOCH(org.apache.arrow.flatbuf.IntervalUnit.EPOCH); private static final IntervalUnit[] valuesByFlatbufId = new IntervalUnit[IntervalUnit.values().length]; diff --git a/java/vector/src/main/java/org/apache/arrow/vector/types/TimeUnit.java b/java/vector/src/main/java/org/apache/arrow/vector/types/TimeUnit.java index ee0e67e5a65..d5908e49a64 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/types/TimeUnit.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/types/TimeUnit.java @@ -21,7 +21,8 @@ public enum TimeUnit { SECOND(org.apache.arrow.flatbuf.TimeUnit.SECOND), MILLISECOND(org.apache.arrow.flatbuf.TimeUnit.MILLISECOND), MICROSECOND(org.apache.arrow.flatbuf.TimeUnit.MICROSECOND), - NANOSECOND(org.apache.arrow.flatbuf.TimeUnit.NANOSECOND); + NANOSECOND(org.apache.arrow.flatbuf.TimeUnit.NANOSECOND), + NOT_APPLICABLE(org.apache.arrow.flatbuf.TimeUnit.NOT_APPLICABLE); private static final TimeUnit[] valuesByFlatbufId = new TimeUnit[TimeUnit.values().length]; diff --git a/java/vector/src/main/java/org/apache/arrow/vector/types/Types.java b/java/vector/src/main/java/org/apache/arrow/vector/types/Types.java index a505821f0bc..c718d6af1f3 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/types/Types.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/types/Types.java @@ -33,6 +33,7 @@ import org.apache.arrow.vector.Float8Vector; import org.apache.arrow.vector.IntVector; import org.apache.arrow.vector.IntervalDayVector; +import org.apache.arrow.vector.IntervalEpochSecondVector; import org.apache.arrow.vector.IntervalYearVector; import org.apache.arrow.vector.SmallIntVector; import org.apache.arrow.vector.TimeMicroVector; @@ -70,6 +71,7 @@ import org.apache.arrow.vector.complex.impl.Float8WriterImpl; import org.apache.arrow.vector.complex.impl.IntWriterImpl; import org.apache.arrow.vector.complex.impl.IntervalDayWriterImpl; +import org.apache.arrow.vector.complex.impl.IntervalEpochSecondWriterImpl; import org.apache.arrow.vector.complex.impl.IntervalYearWriterImpl; import org.apache.arrow.vector.complex.impl.NullableStructWriter; import org.apache.arrow.vector.complex.impl.SmallIntWriterImpl; @@ -363,7 +365,7 @@ public FieldWriter getNewFieldWriter(ValueVector vector) { return new TimeStampNanoWriterImpl((TimeStampNanoVector) vector); } }, - INTERVALDAY(new Interval(IntervalUnit.DAY_TIME)) { + INTERVALDAY(new Interval(IntervalUnit.DAY_TIME, TimeUnit.NOT_APPLICABLE)) { @Override public FieldVector getNewVector( String name, @@ -378,7 +380,22 @@ public FieldWriter getNewFieldWriter(ValueVector vector) { return new IntervalDayWriterImpl((IntervalDayVector) vector); } }, - INTERVALYEAR(new Interval(IntervalUnit.YEAR_MONTH)) { + INTERVALEPOCHSECOND(new Interval(IntervalUnit.EPOCH, TimeUnit.SECOND)) { + @Override + public FieldVector getNewVector( + String name, + FieldType fieldType, + BufferAllocator allocator, + CallBack schemaChangeCallback) { + return new IntervalEpochSecondVector(name, fieldType, allocator); + } + + @Override + public FieldWriter getNewFieldWriter(ValueVector vector) { + return new IntervalEpochSecondWriterImpl((IntervalEpochSecondVector) vector); + } + }, + INTERVALYEAR(new Interval(IntervalUnit.YEAR_MONTH, TimeUnit.NOT_APPLICABLE )) { @Override public FieldVector getNewVector( String name, @@ -822,7 +839,18 @@ public MinorType visit(Timestamp type) { @Override public MinorType visit(Interval type) { - switch (type.getUnit()) { + switch (type.getType()) { + case EPOCH: + switch (type.getUnit()) { + case SECOND: + return MinorType.INTERVALEPOCHSECOND; + case MILLISECOND: + case MICROSECOND: + case NANOSECOND: + case NOT_APPLICABLE: + default: + throw new IllegalArgumentException("unknown unit: " + type); + } case DAY_TIME: return MinorType.INTERVALDAY; case YEAR_MONTH: diff --git a/java/vector/src/test/java/org/apache/arrow/vector/types/pojo/TestSchema.java b/java/vector/src/test/java/org/apache/arrow/vector/types/pojo/TestSchema.java index 2b109dce77a..fc9e6211bc7 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/types/pojo/TestSchema.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/types/pojo/TestSchema.java @@ -66,13 +66,13 @@ public void testComplex() throws IOException { field("f", new FloatingPoint(FloatingPointPrecision.SINGLE)), field("g", new Timestamp(TimeUnit.MILLISECOND, "UTC")), field("h", new Timestamp(TimeUnit.MICROSECOND, null)), - field("i", new Interval(IntervalUnit.DAY_TIME)) + field("i", new Interval(IntervalUnit.DAY_TIME, TimeUnit.NOT_APPLICABLE)) )); roundTrip(schema); assertEquals( "Schema, e: List, " + "f: FloatingPoint(SINGLE), g: Timestamp(MILLISECOND, UTC), h: Timestamp(MICROSECOND, null), " + - "i: Interval(DAY_TIME)>", + "i: Interval(DAY_TIME, NOT_APPLICABLE)>", schema.toString()); } @@ -97,7 +97,7 @@ public void testAll() throws IOException { field("p", new Time(TimeUnit.NANOSECOND, 64)), field("q", new Timestamp(TimeUnit.MILLISECOND, "UTC")), field("r", new Timestamp(TimeUnit.MICROSECOND, null)), - field("s", new Interval(IntervalUnit.DAY_TIME)), + field("s", new Interval(IntervalUnit.DAY_TIME, TimeUnit.NOT_APPLICABLE)), field("t", new FixedSizeBinary(100)) )); roundTrip(schema); @@ -161,8 +161,8 @@ public void testTS() throws IOException { @Test public void testInterval() throws IOException { Schema schema = new Schema(asList( - field("a", new Interval(IntervalUnit.YEAR_MONTH)), - field("b", new Interval(IntervalUnit.DAY_TIME)) + field("a", new Interval(IntervalUnit.YEAR_MONTH, TimeUnit.NOT_APPLICABLE)), + field("b", new Interval(IntervalUnit.DAY_TIME, TimeUnit.NOT_APPLICABLE)) )); roundTrip(schema); contains(schema, "YEAR_MONTH", "DAY_TIME");