From f819459b43716f2b57fd4f7fc9150f4c3f9ad725 Mon Sep 17 00:00:00 2001 From: Larry White Date: Thu, 29 Sep 2022 11:16:53 -0400 Subject: [PATCH 01/40] initial commit of Table support --- .../apache/arrow/vector/table/BaseCursor.java | 75 + .../apache/arrow/vector/table/BaseTable.java | 398 ++++ .../org/apache/arrow/vector/table/Cursor.java | 1808 +++++++++++++++++ .../org/apache/arrow/vector/table/Table.java | 187 ++ .../arrow/vector/table/BaseTableTest.java | 252 +++ .../apache/arrow/vector/table/CursorTest.java | 286 +++ .../apache/arrow/vector/table/TableTest.java | 228 +++ .../apache/arrow/vector/table/TestUtils.java | 280 +++ 8 files changed, 3514 insertions(+) create mode 100644 java/vector/src/main/java/org/apache/arrow/vector/table/BaseCursor.java create mode 100644 java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java create mode 100644 java/vector/src/main/java/org/apache/arrow/vector/table/Cursor.java create mode 100644 java/vector/src/main/java/org/apache/arrow/vector/table/Table.java create mode 100644 java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java create mode 100644 java/vector/src/test/java/org/apache/arrow/vector/table/CursorTest.java create mode 100644 java/vector/src/test/java/org/apache/arrow/vector/table/TableTest.java create mode 100644 java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/BaseCursor.java b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseCursor.java new file mode 100644 index 00000000000..05317eb2ad4 --- /dev/null +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseCursor.java @@ -0,0 +1,75 @@ +/* + * 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.table; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; + +/** + * Provides row based access to the data held by a {@link Table}. + */ +public abstract class BaseCursor { + + /** The table we're enumerating. */ + protected final BaseTable table; + + /** the current row number. */ + protected int rowNumber = -1; + + /** + * Returns the standard character set to use for decoding strings. Can be overridden for + * individual columns by providing the {@link Charset} as an argument in the getter. + */ + private Charset defaultCharacterSet = StandardCharsets.UTF_8; + + /** + * Constructs a new BaseCursor backed by the given table. + * + * @param table the table that this MutableCursor object represents + */ + public BaseCursor(BaseTable table) { + this.table = table; + } + + /** + * Constructs a new BaseCursor backed by the given table. + * + * @param table the table that this cursor represents + * @param charset the standard charset for decoding bytes into strings. Note: This can be + * overridden for individual columns. + */ + public BaseCursor(BaseTable table, Charset charset) { + this.table = table; + this.defaultCharacterSet = charset; + } + + /** + * Resets the row index to -1 and returns this object. + */ + BaseCursor resetPosition() { + rowNumber = -1; + return this; + } + + /** + * Returns the default character set for use with character vectors. + */ + public Charset getDefaultCharacterSet() { + return defaultCharacterSet; + } +} diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java new file mode 100644 index 00000000000..6fd4b126b15 --- /dev/null +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java @@ -0,0 +1,398 @@ +/* + * 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.table; + +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.apache.arrow.util.AutoCloseables; +import org.apache.arrow.util.Preconditions; +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.ValueVector; +import org.apache.arrow.vector.VectorSchemaRoot; +import org.apache.arrow.vector.complex.reader.FieldReader; +import org.apache.arrow.vector.dictionary.Dictionary; +import org.apache.arrow.vector.dictionary.DictionaryEncoder; +import org.apache.arrow.vector.dictionary.DictionaryProvider; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.arrow.vector.types.pojo.Schema; +import org.apache.arrow.vector.util.TransferPair; + +/** Abstract base class for Table with mutable and immutable concrete implementations. */ +public abstract class BaseTable implements AutoCloseable { + + /** The field vectors holding the data in this table. */ + protected final List fieldVectors; + + /** + * An optional DictionaryProvider. One must be present if any vector in the table is dictionary + * encoded. + */ + protected DictionaryProvider dictionaryProvider; + + /** A map of Fields to FieldVectors used to select Fields. */ + protected final Map fieldVectorsMap = new LinkedHashMap<>(); + + /** The schema for the table. */ + protected Schema schema; + + /** The number of rows of data in the table; not necessarily the same as the table row capacity. */ + protected int rowCount; + + /** + * Constructs new instance with the given rowCount, and containing the schema and each of the + * given vectors. + * + * @param fieldVectors the FieldVectors containing the table's data + * @param rowCount the number of rows in the table + * @param provider a dictionary provider, may be null if none of the vectors in the table are + * encoded + */ + public BaseTable(List fieldVectors, int rowCount, DictionaryProvider provider) { + + this.dictionaryProvider = provider; + this.rowCount = rowCount; + this.fieldVectors = new ArrayList<>(); + List fields = new ArrayList<>(); + for (FieldVector fv : fieldVectors) { + TransferPair transferPair = fv.getTransferPair(fv.getAllocator()); + transferPair.transfer(); + FieldVector newVector = (FieldVector) transferPair.getTo(); + newVector.setValueCount(rowCount); + + Field newField = newVector.getField(); + this.fieldVectors.add(newVector); + fields.add(newField); + fieldVectorsMap.put(newField, newVector); + } + this.schema = new Schema(fields); + } + + /** + * Returns a FieldReader for the vector with the given name. + * + * @param name The name of a vector in this Table (case-sensitive) + * @return A FieldReader for the named FieldVector + */ + public FieldReader getReader(String name) { + for (Map.Entry entry : fieldVectorsMap.entrySet()) { + if (entry.getKey().getName().equals(name)) { + return entry.getValue().getReader(); + } + } + return null; + } + + /** + * Returns a FieldReader for the given field. + * + * @param field The field to be read + * @return A FieldReader for the given field + */ + public FieldReader getReader(Field field) { + return fieldVectorsMap.get(field).getReader(); + } + + /** + * Returns a FieldReader for the field at the given vector index. + * + * @param index The 0-based index of the field desired. + * @return A FieldReader for the requested field + */ + public FieldReader getReader(int index) { + Preconditions.checkArgument(index >= 0 && index < fieldVectors.size()); + return fieldVectors.get(index).getReader(); + } + + /** + * Returns the schema for this Table. + */ + public Schema getSchema() { + return schema; + } + + /** + * Returns the Field with the given name if one exists in this table. + * + * @param fieldName the name of the field to return + * @return a field with the given name if one is present + * @throws IllegalArgumentException – if the field was not found + */ + public Field getField(String fieldName) { + return getSchema().findField(fieldName); + } + + /** + * Returns a list of Field created by adding the given vector to the vectors in this Table. + * + * @param index field index + * @param vector vector to be added. + * @return out List of FieldVectors with vector added + */ + List insertVector(int index, FieldVector vector) { + Preconditions.checkNotNull(vector); + Preconditions.checkArgument(index >= 0 && index <= fieldVectors.size()); + List newVectors = new ArrayList<>(); + if (index == fieldVectors.size()) { + newVectors.addAll(fieldVectors); + newVectors.add(vector); + } else { + for (int i = 0; i < fieldVectors.size(); i++) { + if (i == index) { + newVectors.add(vector); + } + newVectors.add(fieldVectors.get(i)); + } + } + return newVectors; + } + + /** + * Returns a new List of FieldVectors created by removing the selected Vector from the list in + * this Table. + * + * @param index field index + * @return out List of FieldVectors like the list in this table, but with the argument removed + */ + List extractVector(int index) { + Preconditions.checkArgument(index >= 0 && index < fieldVectors.size()); + List newVectors = new ArrayList<>(); + for (int i = 0; i < fieldVectors.size(); i++) { + if (i != index) { + newVectors.add(fieldVectors.get(i)); + } + } + return newVectors; + } + + /** Returns the number of vectors (columns) in this table. */ + public int getVectorCount() { + return fieldVectors.size(); + } + + /** + * Closes all the vectors holding data for this table and sets the rowcount to 0, preventing + * enumeration. + */ + void clear() { + close(); + rowCount = 0; + } + + /** Closes all the vectors holding data for this table. */ + @Override + public void close() { + try { + AutoCloseables.close(fieldVectors); + } catch (RuntimeException ex) { + throw ex; + } catch (Exception ex) { + // should never happen since FieldVector.close() doesn't throw IOException + throw new RuntimeException(ex); + } + } + + /** Returns the number of rows in this table. */ + public long getRowCount() { + return rowCount; + } + + /** + * Returns a new VectorSchemaRoot with the data and schema from this table. Data is transferred to + * the new VectorSchemaRoot, so this table is cleared and the rowCount is set to 0; + * + * @return a new VectorSchemaRoot + */ + public VectorSchemaRoot toVectorSchemaRoot() { + VectorSchemaRoot vsr = + new VectorSchemaRoot( + fieldVectors.stream() + .map( + v -> { + TransferPair transferPair = v.getTransferPair(v.getAllocator()); + transferPair.transfer(); + return (FieldVector) transferPair.getTo(); + }) + .collect(Collectors.toList())); + clear(); + return vsr; + } + + /** + * Returns the vector with the given name, or {@code null} if the name is not found. Names are + * case-sensitive. + * + *

TODO: Consider whether we could avoid doing a linear search of the entries + * + * @param columnName The name of the vector + * @return the Vector with the given name, or null + */ + FieldVector getVector(String columnName) { + for (Map.Entry entry : fieldVectorsMap.entrySet()) { + if (entry.getKey().getName().equals(columnName)) { + return entry.getValue(); + } + } + return null; + } + + /** + * Returns the vector at the given position. + * + * @param columnIndex The 0-based position of the vector + */ + FieldVector getVector(int columnIndex) { + return fieldVectors.get(columnIndex); + } + + /** + * Returns an immutable Cursor object holding a reference to this table. The default character + * encoding used by the cursor to decode Strings will be StandardCharsets.UTF_8. + */ + public Cursor immutableCursor() { + return new Cursor(this); + } + + /** + * Returns an immutable Cursor object holding a reference to this table. + * + * @param defaultCharset The default character encoding used by the cursor to decode Strings. It + * can be overridden for individual vectors in the get() method + */ + public Cursor immutableCursor(Charset defaultCharset) { + return new Cursor(this, defaultCharset); + } + + /** + * Returns a tab separated value of vectors (based on their java object representation). + * + * TODO: Consider moving to a separate object so code can be shared with VSR + */ + public String contentToTSVString() { + StringBuilder sb = new StringBuilder(); + List row = new ArrayList<>(schema.getFields().size()); + for (Field field : schema.getFields()) { + row.add(field.getName()); + } + printRow(sb, row); + for (int i = 0; i < rowCount; i++) { + row.clear(); + for (FieldVector v : fieldVectors) { + row.add(v.getObject(i)); + } + printRow(sb, row); + } + return sb.toString(); + } + + /** + * Prints a single row without a header to the given StringBuilder. + * + * @param sb the StringBuilder to write to + * @param row the row to write + */ + private void printRow(StringBuilder sb, List row) { + boolean first = true; + for (Object v : row) { + if (first) { + first = false; + } else { + sb.append("\t"); + } + sb.append(v); + } + sb.append("\n"); + } + + /** + * Returns true if the row at the given index has been deleted and false otherwise. + * + *

If the index is larger than the number of rows, the method returns true. + * + * TODO: Consider renaming to a test that includes the notion of within the valid range + * + * @param rowNumber The 0-based index of the possibly deleted row + * @return true if the row at the index was deleted; false otherwise + */ + public boolean isRowDeleted(int rowNumber) { + return false; + } + + /** Returns the DictionaryProvider for this table. It can be used to decode an encoded values */ + public DictionaryProvider getDictionaryProvider() { + return dictionaryProvider; + } + + /** + * Returns a ValueVector containing the decoded version of the vector with the given name. + * @param vectorName The name of the vector to decode + * @param dictionaryId The identifier for the dictionary to use when decoding. Must match the id returned by the + * dictionary's getId() method. + * @return A ValueVector + */ + public ValueVector decode(String vectorName, long dictionaryId) { + Dictionary dictionary = getDictionary(dictionaryId); + + FieldVector vector = getVector(vectorName); + if (vector == null) { + throw new IllegalArgumentException( + String.format("No vector with name '%s' is present in table", vectorName)); + } + + DictionaryEncoder decoder = new DictionaryEncoder(dictionary, vector.getAllocator()); + return decoder.decode(vector); + } + + /** + * Returns a ValueVector containing the encoded version of the vector with the given name. + * @param vectorName The name of the vector to encode + * @param dictionaryId The identifier for the dictionary to use when encoding. Must match the id returned by the + * dictionary's getId() method. + * @return A ValueVector + */ + public ValueVector encode(String vectorName, long dictionaryId) { + Dictionary dictionary = getDictionary(dictionaryId); + FieldVector vector = getVector(vectorName); + if (vector == null) { + throw new IllegalArgumentException( + String.format("No vector with name '%s' is present in table", vectorName)); + } + DictionaryEncoder decoder = new DictionaryEncoder(dictionary, vector.getAllocator()); + return decoder.encode(vector); + } + + /** + * Returns the dictionary with given id. + * @param dictionaryId A long integer that is the id returned by the dictionary's getId() method + */ + private Dictionary getDictionary(long dictionaryId) { + if (dictionaryProvider == null) { + throw new IllegalStateException("No dictionary provider is present in table."); + } + + Dictionary dictionary = dictionaryProvider.lookup(dictionaryId); + if (dictionary == null) { + throw new IllegalArgumentException("No dictionary with id '%n' exists in the table"); + } + return dictionary; + } +} diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/Cursor.java b/java/vector/src/main/java/org/apache/arrow/vector/table/Cursor.java new file mode 100644 index 00000000000..98b4afa4885 --- /dev/null +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/Cursor.java @@ -0,0 +1,1808 @@ +/* + * 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.table; + +import java.math.BigDecimal; +import java.nio.charset.Charset; +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.Period; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +import org.apache.arrow.memory.ArrowBuf; +import org.apache.arrow.vector.BigIntVector; +import org.apache.arrow.vector.BitVector; +import org.apache.arrow.vector.DecimalVector; +import org.apache.arrow.vector.DurationVector; +import org.apache.arrow.vector.ExtensionTypeVector; +import org.apache.arrow.vector.FixedSizeBinaryVector; +import org.apache.arrow.vector.Float4Vector; +import org.apache.arrow.vector.Float8Vector; +import org.apache.arrow.vector.IntVector; +import org.apache.arrow.vector.IntervalDayVector; +import org.apache.arrow.vector.IntervalMonthDayNanoVector; +import org.apache.arrow.vector.IntervalYearVector; +import org.apache.arrow.vector.LargeVarBinaryVector; +import org.apache.arrow.vector.LargeVarCharVector; +import org.apache.arrow.vector.PeriodDuration; +import org.apache.arrow.vector.SmallIntVector; +import org.apache.arrow.vector.TimeMicroVector; +import org.apache.arrow.vector.TimeMilliVector; +import org.apache.arrow.vector.TimeNanoVector; +import org.apache.arrow.vector.TimeSecVector; +import org.apache.arrow.vector.TimeStampMicroTZVector; +import org.apache.arrow.vector.TimeStampMicroVector; +import org.apache.arrow.vector.TimeStampMilliTZVector; +import org.apache.arrow.vector.TimeStampMilliVector; +import org.apache.arrow.vector.TimeStampNanoTZVector; +import org.apache.arrow.vector.TimeStampNanoVector; +import org.apache.arrow.vector.TimeStampSecTZVector; +import org.apache.arrow.vector.TimeStampSecVector; +import org.apache.arrow.vector.TinyIntVector; +import org.apache.arrow.vector.UInt1Vector; +import org.apache.arrow.vector.UInt2Vector; +import org.apache.arrow.vector.UInt4Vector; +import org.apache.arrow.vector.UInt8Vector; +import org.apache.arrow.vector.ValueVector; +import org.apache.arrow.vector.VarBinaryVector; +import org.apache.arrow.vector.VarCharVector; +import org.apache.arrow.vector.complex.DenseUnionVector; +import org.apache.arrow.vector.complex.ListVector; +import org.apache.arrow.vector.complex.StructVector; +import org.apache.arrow.vector.complex.UnionVector; +import org.apache.arrow.vector.holders.NullableBigIntHolder; +import org.apache.arrow.vector.holders.NullableBitHolder; +import org.apache.arrow.vector.holders.NullableDurationHolder; +import org.apache.arrow.vector.holders.NullableFloat4Holder; +import org.apache.arrow.vector.holders.NullableFloat8Holder; +import org.apache.arrow.vector.holders.NullableIntHolder; +import org.apache.arrow.vector.holders.NullableIntervalDayHolder; +import org.apache.arrow.vector.holders.NullableIntervalMonthDayNanoHolder; +import org.apache.arrow.vector.holders.NullableSmallIntHolder; +import org.apache.arrow.vector.holders.NullableTimeMicroHolder; +import org.apache.arrow.vector.holders.NullableTimeMilliHolder; +import org.apache.arrow.vector.holders.NullableTimeNanoHolder; +import org.apache.arrow.vector.holders.NullableTimeSecHolder; +import org.apache.arrow.vector.holders.NullableTimeStampMicroHolder; +import org.apache.arrow.vector.holders.NullableTimeStampMicroTZHolder; +import org.apache.arrow.vector.holders.NullableTimeStampMilliHolder; +import org.apache.arrow.vector.holders.NullableTimeStampMilliTZHolder; +import org.apache.arrow.vector.holders.NullableTimeStampNanoHolder; +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.NullableTinyIntHolder; +import org.apache.arrow.vector.holders.NullableUInt1Holder; +import org.apache.arrow.vector.holders.NullableUInt2Holder; +import org.apache.arrow.vector.holders.NullableUInt4Holder; +import org.apache.arrow.vector.holders.NullableUInt8Holder; + +/** + * Cursor is a positionable, immutable cursor backed by a {@link Table}. If a row in a table is + * marked as deleted, it is skipped when iterating. + * + *

Getters are provided for most vector types. The exceptions being {@link org.apache.arrow.vector.NullVector}, + * which only contains null values and has no getter, and {@link org.apache.arrow.vector.ZeroVector}, + * which is a zero-length vector of any type + */ +public class Cursor extends BaseCursor implements Iterator { + + /** Indicates whether the next non-deleted row has been determined yet. */ + private boolean nextRowSet; + + /** + * An iterator that returns every row in the table, deleted or not. The implemented next() and + * hasNext() methods in Cursor wrap it with a filter to get only the non-deleted ones. + */ + private final Iterator iterator = intIterator(); + + /** + * Constructs a new BaseCursor backed by the given table. + * + * @param table the table that this Cursor object represents + */ + public Cursor(BaseTable table) { + super(table); + } + + /** + * Constructs a newCursor backed by the given table. + * + * @param table the table that this Cursor object represents + * @param charset the standard charset for decoding bytes into strings. Note: This can be + * overridden for individual columns + */ + public Cursor(BaseTable table, Charset charset) { + super(table, charset); + } + + /** + * Resets the current row to -1 and returns this object. + */ + @Override + Cursor resetPosition() { + return (Cursor) super.resetPosition(); + } + + /** + * Moves this Cursor to the given 0-based row index. + * + * @return this Cursor for chaining + */ + public Cursor setPosition(int rowNumber) { + this.rowNumber = rowNumber; + this.nextRowSet = false; + return this; + } + + /** + * For vectors other than Union and DenseUnion, returns true if the value at columnName is null, + * and false otherwise. + * + *

UnionVector#isNull always returns false, but the underlying vector may hold null values. + */ + public boolean isNull(String columnName) { + ValueVector vector = table.getVector(columnName); + return vector.isNull(rowNumber); + } + + /** Returns true if the value at columnName is null, and false otherwise. */ + public boolean isNull(int columnIndex) { + ValueVector vector = table.getVector(columnIndex); + return vector.isNull(rowNumber); + } + + /** + * Returns an object representing the value in the named ExtensionTypeVector at the currentRow. An + * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalArgumentException is thrown if the type is incorrect. + */ + public Object getExtensionType(int vectorIndex) { + ExtensionTypeVector vector = (ExtensionTypeVector) table.getVector(vectorIndex); + return vector.getObject(rowNumber); + } + + /** + * Returns an object representing the value in the ExtensionTypeVector at the currentRow. An + * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalArgumentException is thrown if it has a different type. + * + * @param columnName The name of the vector providing the result + * @return The object in the named column at the current row + */ + public Object getExtensionType(String columnName) { + ExtensionTypeVector vector = (ExtensionTypeVector) table.getVector(columnName); + return vector.getObject(rowNumber); + } + + /** + * Returns a Map from the column of the given name at the current row. An IllegalStateException is + * thrown if the column is not present in the Cursor and an IllegalArgumentException is thrown if + * it has a different type. + */ + public List getMap(int vectorIndex) { + ListVector vector = (ListVector) table.getVector(vectorIndex); + return vector.getObject(rowNumber); + } + + /** + * Returns a Map from the column of the given name at the current row. An IllegalStateException is + * thrown if the column is not present in the Cursor and an IllegalArgumentException is thrown if + * it has a different type + */ + public List getMap(String columnName) { + ListVector vector = (ListVector) table.getVector(columnName); + return vector.getObject(rowNumber); + } + + /** + * Returns an Object from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalArgumentException is thrown if it has a different type + */ + public Object getStruct(int vectorIndex) { + StructVector vector = (StructVector) table.getVector(vectorIndex); + return vector.getObject(rowNumber); + } + + /** + * Returns an Object from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalArgumentException is thrown if it has a different type + */ + public Object getStruct(String columnName) { + StructVector vector = (StructVector) table.getVector(columnName); + return vector.getObject(rowNumber); + } + + /** + * Returns a List from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalArgumentException is thrown if it has a different type + */ + public Object getUnion(int vectorIndex) { + UnionVector vector = (UnionVector) table.getVector(vectorIndex); + return vector.getObject(rowNumber); + } + + /** + * Returns an object from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalArgumentException is thrown if it has a different type + */ + public Object getUnion(String columnName) { + UnionVector vector = (UnionVector) table.getVector(columnName); + return vector.getObject(rowNumber); + } + + /** + * Returns an object from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalArgumentException is thrown if it has a different type + */ + public Object getDenseUnion(String columnName) { + DenseUnionVector vector = (DenseUnionVector) table.getVector(columnName); + return vector.getObject(rowNumber); + } + + /** + * Returns a List from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalArgumentException is thrown if it has a different type + */ + public Object getDenseUnion(int vectorIndex) { + DenseUnionVector vector = (DenseUnionVector) table.getVector(vectorIndex); + return vector.getObject(rowNumber); + } + + /** + * Returns a List from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present in the Cursor and an IllegalArgumentException is thrown + * if it has a different type + */ + public List getList(String columnName) { + ListVector vector = (ListVector) table.getVector(columnName); + return vector.getObject(rowNumber); + } + + /** + * Returns a List from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present and an IllegalArgumentException is + * thrown if it has a different type + */ + public List getList(int columnIndex) { + ListVector vector = (ListVector) table.getVector(columnIndex); + return vector.getObject(rowNumber); + } + + /** + * Returns an int from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present in the Cursor and an IllegalArgumentException is thrown + * if it has a different type + */ + public int getInt(String columnName) { + IntVector vector = (IntVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns an int from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present and an IllegalArgumentException is + * thrown if it has a different type + */ + public int getInt(int columnIndex) { + IntVector vector = (IntVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Updates the holder with the value at the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalArgumentException is thrown if it has a different type + */ + public void getInt(String columnName, NullableIntHolder holder) { + IntVector vector = (IntVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Updates the holder with the value at the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present and an IllegalArgumentException is + * thrown if it has a different type + */ + public void getInt(int columnIndex, NullableIntHolder holder) { + IntVector vector = (IntVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns an int from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present in the Cursor and an IllegalArgumentException is thrown + * if it has a different type + */ + public int getUInt4(String columnName) { + UInt4Vector vector = (UInt4Vector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns an int from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present and an IllegalArgumentException is + * thrown if it has a different type + */ + public int getUInt4(int columnIndex) { + UInt4Vector vector = (UInt4Vector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Updates the holder with the value at the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalArgumentException is thrown if it has a different type + */ + public void getUInt4(String columnName, NullableUInt4Holder holder) { + UInt4Vector vector = (UInt4Vector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Updates the holder with the value at the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present and an IllegalArgumentException is + * thrown if it has a different type + */ + public void getUInt4(int columnIndex, NullableUInt4Holder holder) { + UInt4Vector vector = (UInt4Vector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a short from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public short getSmallInt(String columnName) { + SmallIntVector vector = (SmallIntVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a short from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public short getSmallInt(int columnIndex) { + SmallIntVector vector = (SmallIntVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Updates the holder with the value at the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getSmallInt(String columnName, NullableSmallIntHolder holder) { + SmallIntVector vector = (SmallIntVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Updates the holder with the value at the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getSmallInt(int columnIndex, NullableSmallIntHolder holder) { + SmallIntVector vector = (SmallIntVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a char from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public char getUInt2(String columnName) { + UInt2Vector vector = (UInt2Vector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a char from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public char getUInt2(int columnIndex) { + UInt2Vector vector = (UInt2Vector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Updates the holder with the value at the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getUInt2(String columnName, NullableUInt2Holder holder) { + UInt2Vector vector = (UInt2Vector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Updates the holder with the value at the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getUInt2(int columnIndex, NullableUInt2Holder holder) { + UInt2Vector vector = (UInt2Vector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a byte from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public byte getTinyInt(String columnName) { + TinyIntVector vector = (TinyIntVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a byte from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public byte getTinyInt(int columnIndex) { + TinyIntVector vector = (TinyIntVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Updates the holder with the value at the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getTinyInt(String columnName, NullableTinyIntHolder holder) { + TinyIntVector vector = (TinyIntVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Updates the holder with the value at the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getTinyInt(int columnIndex, NullableTinyIntHolder holder) { + TinyIntVector vector = (TinyIntVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a byte from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public byte getUInt1(String columnName) { + UInt1Vector vector = (UInt1Vector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a byte from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public byte getUInt1(int columnIndex) { + UInt1Vector vector = (UInt1Vector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Updates the holder with the value at the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getUInt1(String columnName, NullableUInt1Holder holder) { + UInt1Vector vector = (UInt1Vector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Updates the holder with the value at the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getUInt1(int columnIndex, NullableUInt1Holder holder) { + UInt1Vector vector = (UInt1Vector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public long getBigInt(String columnName) { + BigIntVector vector = (BigIntVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public long getBigInt(int columnIndex) { + BigIntVector vector = (BigIntVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Updates the holder with the value at the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getBigInt(String columnName, NullableBigIntHolder holder) { + BigIntVector vector = (BigIntVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Updates the holder with the value at the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getBigInt(int columnIndex, NullableBigIntHolder holder) { + BigIntVector vector = (BigIntVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public long getUInt8(String columnName) { + UInt8Vector vector = (UInt8Vector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public long getUInt8(int columnIndex) { + UInt8Vector vector = (UInt8Vector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Updates the holder with the value at the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getUInt8(String columnName, NullableUInt8Holder holder) { + UInt8Vector vector = (UInt8Vector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Updates the holder with the value at the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getUInt8(int columnIndex, NullableUInt8Holder holder) { + UInt8Vector vector = (UInt8Vector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a float from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public float getFloat4(String columnName) { + Float4Vector vector = (Float4Vector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public float getFloat4(int columnIndex) { + Float4Vector vector = (Float4Vector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Updates the holder with the value at the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getFloat4(String columnName, NullableFloat4Holder holder) { + Float4Vector vector = (Float4Vector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Updates the holder with the value at the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getFloat4(int columnIndex, NullableFloat4Holder holder) { + Float4Vector vector = (Float4Vector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a double from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public double getFloat8(String columnName) { + Float8Vector vector = (Float8Vector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a double from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public double getFloat8(int columnIndex) { + Float8Vector vector = (Float8Vector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns a double from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public void getFloat8(String columnName, NullableFloat8Holder holder) { + Float8Vector vector = (Float8Vector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Updates the holder with the value at the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getFloat8(int columnIndex, NullableFloat8Holder holder) { + Float8Vector vector = (Float8Vector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Updates the holder with the value at the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public int getBit(String columnName) { + BitVector vector = (BitVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns an int from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public int getBit(int columnIndex) { + BitVector vector = (BitVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Updates the holder with the value at the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getBit(String columnName, NullableBitHolder holder) { + BitVector vector = (BitVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Updates the holder with the value at the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getBit(int columnIndex, NullableBitHolder holder) { + BitVector vector = (BitVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public long getTimeNano(String columnName) { + TimeNanoVector vector = (TimeNanoVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public long getTimeNano(int columnIndex) { + TimeNanoVector vector = (TimeNanoVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public void getTimeNano(String columnName, NullableTimeNanoHolder holder) { + TimeNanoVector vector = (TimeNanoVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type. + */ + public void getTimeNano(int columnIndex, NullableTimeNanoHolder holder) { + TimeNanoVector vector = (TimeNanoVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type. + */ + public long getTimeMicro(String columnName) { + TimeMicroVector vector = (TimeMicroVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type. + */ + public long getTimeMicro(int columnIndex) { + TimeMicroVector vector = (TimeMicroVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type. + */ + public void getTimeMicro(String columnName, NullableTimeMicroHolder holder) { + TimeMicroVector vector = (TimeMicroVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type. + */ + public void getTimeMicro(int columnIndex, NullableTimeMicroHolder holder) { + TimeMicroVector vector = (TimeMicroVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns an int from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type. + */ + public int getTimeMilli(String columnName) { + TimeMilliVector vector = (TimeMilliVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns an int from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type. + */ + public int getTimeMilli(int columnIndex) { + TimeMilliVector vector = (TimeMilliVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns an int from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type. + */ + public void getTimeMilli(String columnName, NullableTimeMilliHolder holder) { + TimeMilliVector vector = (TimeMilliVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Returns an int from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type. + */ + public void getTimeMilli(int columnIndex, NullableTimeMilliHolder holder) { + TimeMilliVector vector = (TimeMilliVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns an int from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type. + */ + public LocalDateTime getTimeMilliObj(String columnName) { + TimeMilliVector vector = (TimeMilliVector) table.getVector(columnName); + return vector.getObject(rowNumber); + } + + /** + * Returns an int from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type. + */ + public LocalDateTime getTimeMilliObj(int columnIndex) { + TimeMilliVector vector = (TimeMilliVector) table.getVector(columnIndex); + return vector.getObject(rowNumber); + } + + /** + * Returns an int from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type. + */ + public int getTimeSec(String columnName) { + TimeSecVector vector = (TimeSecVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns an int from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type. + */ + public int getTimeSec(int columnIndex) { + TimeSecVector vector = (TimeSecVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns an int from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type. + */ + public void getTimeSec(String columnName, NullableTimeSecHolder holder) { + TimeSecVector vector = (TimeSecVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Returns an int from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type. + */ + public void getTimeSec(int columnIndex, NullableTimeSecHolder holder) { + TimeSecVector vector = (TimeSecVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type. + */ + public long getTimeStampSec(String columnName) { + TimeStampSecVector vector = (TimeStampSecVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public long getTimeStampSec(int columnIndex) { + TimeStampSecVector vector = (TimeStampSecVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public void getTimeStampSec(String columnName, NullableTimeStampSecHolder holder) { + TimeStampSecVector vector = (TimeStampSecVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getTimeStampSec(int columnIndex, NullableTimeStampSecHolder holder) { + TimeStampSecVector vector = (TimeStampSecVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public LocalDateTime getTimeStampSecObj(String columnName) { + TimeStampSecVector vector = (TimeStampSecVector) table.getVector(columnName); + return vector.getObject(rowNumber); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public LocalDateTime getTimeStampSecObj(int columnIndex) { + TimeStampSecVector vector = (TimeStampSecVector) table.getVector(columnIndex); + return vector.getObject(rowNumber); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public long getTimeStampSecTZ(String columnName) { + TimeStampSecTZVector vector = (TimeStampSecTZVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public long getTimeStampSecTZ(int columnIndex) { + TimeStampSecTZVector vector = (TimeStampSecTZVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public void getTimeStampSecTZ(String columnName, NullableTimeStampSecTZHolder holder) { + TimeStampSecTZVector vector = (TimeStampSecTZVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getTimeStampSecTZ(int columnIndex, NullableTimeStampSecTZHolder holder) { + TimeStampSecTZVector vector = (TimeStampSecTZVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public long getTimeStampNano(String columnName) { + TimeStampNanoVector vector = (TimeStampNanoVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public long getTimeStampNano(int columnIndex) { + TimeStampNanoVector vector = (TimeStampNanoVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public void getTimeStampNano(String columnName, NullableTimeStampNanoHolder holder) { + TimeStampNanoVector vector = (TimeStampNanoVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getTimeStampNano(int columnIndex, NullableTimeStampNanoHolder holder) { + TimeStampNanoVector vector = (TimeStampNanoVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a LocalDateTime from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public LocalDateTime getTimeStampNanoObj(String columnName) { + TimeStampNanoVector vector = (TimeStampNanoVector) table.getVector(columnName); + return vector.getObject(rowNumber); + } + + /** + * Returns a LocalDateTime from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public LocalDateTime getTimeStampNanoObj(int columnIndex) { + TimeStampNanoVector vector = (TimeStampNanoVector) table.getVector(columnIndex); + return vector.getObject(rowNumber); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public long getTimeStampNanoTZ(String columnName) { + TimeStampNanoTZVector vector = (TimeStampNanoTZVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public long getTimeStampNanoTZ(int columnIndex) { + TimeStampNanoTZVector vector = (TimeStampNanoTZVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public void getTimeStampNanoTZ(String columnName, NullableTimeStampNanoTZHolder holder) { + TimeStampNanoTZVector vector = (TimeStampNanoTZVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getTimeStampNanoTZ(int columnIndex, NullableTimeStampNanoTZHolder holder) { + TimeStampNanoTZVector vector = (TimeStampNanoTZVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public long getTimeStampMilli(String columnName) { + TimeStampMilliVector vector = (TimeStampMilliVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public long getTimeStampMilli(int columnIndex) { + TimeStampMilliVector vector = (TimeStampMilliVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public void getTimeStampMilli(String columnName, NullableTimeStampMilliHolder holder) { + TimeStampMilliVector vector = (TimeStampMilliVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getTimeStampMilli(int columnIndex, NullableTimeStampMilliHolder holder) { + TimeStampMilliVector vector = (TimeStampMilliVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a LocalDateTime from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public LocalDateTime getTimeStampMilliObj(String columnName) { + TimeStampMilliVector vector = (TimeStampMilliVector) table.getVector(columnName); + return vector.getObject(rowNumber); + } + + /** + * Returns a LocalDateTime from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public LocalDateTime getTimeStampMilliObj(int columnIndex) { + TimeStampMilliVector vector = (TimeStampMilliVector) table.getVector(columnIndex); + return vector.getObject(rowNumber); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public long getTimeStampMilliTZ(String columnName) { + TimeStampMilliTZVector vector = (TimeStampMilliTZVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public long getTimeStampMilliTZ(int columnIndex) { + TimeStampMilliTZVector vector = (TimeStampMilliTZVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different types + */ + public void getTimeStampMilliTZ(String columnName, NullableTimeStampMilliTZHolder holder) { + TimeStampMilliTZVector vector = (TimeStampMilliTZVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getTimeStampMilliTZ(int columnIndex, NullableTimeStampMilliTZHolder holder) { + TimeStampMilliTZVector vector = (TimeStampMilliTZVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public long getTimeStampMicro(String columnName) { + TimeStampMicroVector vector = (TimeStampMicroVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public long getTimeStampMicro(int columnIndex) { + TimeStampMicroVector vector = (TimeStampMicroVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public void getTimeStampMicro(String columnName, NullableTimeStampMicroHolder holder) { + TimeStampMicroVector vector = (TimeStampMicroVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getTimeStampMicro(int columnIndex, NullableTimeStampMicroHolder holder) { + TimeStampMicroVector vector = (TimeStampMicroVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a LocalDateTime from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public LocalDateTime getTimeStampMicroObj(String columnName) { + TimeStampMicroVector vector = (TimeStampMicroVector) table.getVector(columnName); + return vector.getObject(rowNumber); + } + + /** + * Returns a LocalDateTime from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public LocalDateTime getTimeStampMicroObj(int columnIndex) { + TimeStampMicroVector vector = (TimeStampMicroVector) table.getVector(columnIndex); + return vector.getObject(rowNumber); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public long getTimeStampMicroTZ(String columnName) { + TimeStampMicroTZVector vector = (TimeStampMicroTZVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public long getTimeStampMicroTZ(int columnIndex) { + TimeStampMicroTZVector vector = (TimeStampMicroTZVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns a long from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public void getTimeStampMicroTZ(String columnName, NullableTimeStampMicroTZHolder holder) { + TimeStampMicroTZVector vector = (TimeStampMicroTZVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Returns a long from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getTimeStampMicroTZ(int columnIndex, NullableTimeStampMicroTZHolder holder) { + TimeStampMicroTZVector vector = (TimeStampMicroTZVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a Duration from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public Duration getDurationObj(String columnName) { + DurationVector vector = (DurationVector) table.getVector(columnName); + return vector.getObject(rowNumber); + } + + /** + * Returns a Duration from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public Duration getDurationObj(int columnIndex) { + DurationVector vector = (DurationVector) table.getVector(columnIndex); + return vector.getObject(rowNumber); + } + + /** + * Returns a Duration from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public ArrowBuf getDuration(String columnName) { + DurationVector vector = (DurationVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a Duration from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public ArrowBuf getDuration(int columnIndex) { + DurationVector vector = (DurationVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns a Duration from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getDuration(String columnName, NullableDurationHolder holder) { + DurationVector vector = (DurationVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Returns a Duration from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getDuration(int columnIndex, NullableDurationHolder holder) { + DurationVector vector = (DurationVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a PeriodDuration from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public PeriodDuration getIntervalMonthDayNanoObj(String columnName) { + IntervalMonthDayNanoVector vector = (IntervalMonthDayNanoVector) table.getVector(columnName); + return vector.getObject(rowNumber); + } + + /** + * Returns a PeriodDuration from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public PeriodDuration getIntervalMonthDayNanoObj(int columnIndex) { + IntervalMonthDayNanoVector vector = (IntervalMonthDayNanoVector) table.getVector(columnIndex); + return vector.getObject(rowNumber); + } + + /** + * Returns a PeriodDuration from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public ArrowBuf getIntervalMonthDayNano(String columnName) { + IntervalMonthDayNanoVector vector = (IntervalMonthDayNanoVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a PeriodDuration from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public ArrowBuf getIntervalMonthDayNano(int columnIndex) { + IntervalMonthDayNanoVector vector = (IntervalMonthDayNanoVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns a PeriodDuration from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getIntervalMonthDayNano( + String columnName, NullableIntervalMonthDayNanoHolder holder) { + IntervalMonthDayNanoVector vector = (IntervalMonthDayNanoVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Returns a PeriodDuration from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getIntervalMonthDayNano(int columnIndex, NullableIntervalMonthDayNanoHolder holder) { + IntervalMonthDayNanoVector vector = (IntervalMonthDayNanoVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a Duration from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public ArrowBuf getIntervalDay(String columnName) { + IntervalDayVector vector = (IntervalDayVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns an ArrowBuf from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public ArrowBuf getIntervalDay(int columnIndex) { + IntervalDayVector vector = (IntervalDayVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns a Duration from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getIntervalDay(String columnName, NullableIntervalDayHolder holder) { + IntervalDayVector vector = (IntervalDayVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Returns an ArrowBuf from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getIntervalDay(int columnIndex, NullableIntervalDayHolder holder) { + IntervalDayVector vector = (IntervalDayVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Returns a Duration from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public Duration getIntervalDayObj(int columnIndex) { + IntervalDayVector vector = (IntervalDayVector) table.getVector(columnIndex); + return vector.getObject(rowNumber); + } + + /** + * Returns a Duration from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public Duration getIntervalDayObj(String columnName) { + IntervalDayVector vector = (IntervalDayVector) table.getVector(columnName); + return vector.getObject(rowNumber); + } + + /** + * Returns a Period from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public Period getIntervalYearObj(String columnName) { + IntervalYearVector vector = (IntervalYearVector) table.getVector(columnName); + return vector.getObject(rowNumber); + } + + /** + * Returns a Period from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public Period getIntervalYearObj(int columnIndex) { + IntervalYearVector vector = (IntervalYearVector) table.getVector(columnIndex); + return vector.getObject(rowNumber); + } + + /** + * Returns a Period from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public int getIntervalYear(String columnName) { + IntervalYearVector vector = (IntervalYearVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a Period from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public int getIntervalYear(int columnIndex) { + IntervalYearVector vector = (IntervalYearVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns a BigDecimal from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public BigDecimal getDecimalObj(String columnName) { + DecimalVector vector = (DecimalVector) table.getVector(columnName); + return vector.getObject(rowNumber); + } + + /** + * Returns a BigDecimal from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public BigDecimal getDecimalObj(int columnIndex) { + DecimalVector vector = (DecimalVector) table.getVector(columnIndex); + return vector.getObject(rowNumber); + } + + /** + * Returns a BigDecimal from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public ArrowBuf getDecimal(String columnName) { + DecimalVector vector = (DecimalVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a BigDecimal from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public ArrowBuf getDecimal(int columnIndex) { + DecimalVector vector = (DecimalVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns a byte[] from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public byte[] getVarBinary(String columnName) { + VarBinaryVector vector = (VarBinaryVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a byte[] from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public byte[] getVarBinary(int columnIndex) { + VarBinaryVector vector = (VarBinaryVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns a byte[] from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public byte[] getFixedSizeBinary(String columnName) { + FixedSizeBinaryVector vector = (FixedSizeBinaryVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a byte[] from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public byte[] getFixedSizeBinary(int columnIndex) { + FixedSizeBinaryVector vector = (FixedSizeBinaryVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns a byte[] from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * present but has a different type + */ + public byte[] getLargeVarBinary(String columnName) { + LargeVarBinaryVector vector = (LargeVarBinaryVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a byte[] from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public byte[] getLargeVarBinary(int columnIndex) { + LargeVarBinaryVector vector = (LargeVarBinaryVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + + /** + * Returns a String from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present in the Cursor and an IllegalArgumentException is thrown + * if it has a different type + * + *

StandardCharsets.UTF_8 is used as the charset + */ + public String getVarChar(String columnName) { + VarCharVector vector = (VarCharVector) table.getVector(columnName); + return new String(vector.get(rowNumber), getDefaultCharacterSet()); + } + + /** + * Returns a String from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present in the Cursor and an IllegalArgumentException is thrown + * if it has a different type + * + * @param vectorName the name of the FieldVector holding the value + * @param charset the charset to use for decoding the bytes + */ + public String getVarChar(String vectorName, Charset charset) { + VarCharVector vector = (VarCharVector) table.getVector(vectorName); + return new String(vector.get(rowNumber), charset); + } + + /** + * Returns a String from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalArgumentException is thrown if it has a different type + * + * @param columnIndex the index of the FieldVector holding the value + */ + public String getVarChar(int columnIndex) { + VarCharVector vector = (VarCharVector) table.getVector(columnIndex); + return new String(vector.get(rowNumber), getDefaultCharacterSet()); + } + + /** + * Returns a String from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalArgumentException is thrown if it has a different type + * + * @param columnIndex the index of the FieldVector holding the value + * @param charset the charset to use for decoding the bytes + */ + public String getVarChar(int columnIndex, Charset charset) { + VarCharVector vector = (VarCharVector) table.getVector(columnIndex); + return new String(vector.get(rowNumber), charset); + } + + /** + * Returns a String from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present in the Cursor and an IllegalArgumentException is thrown + * if it has a different type + * + *

StandardCharsets.UTF_8 is used as the charset, unless this cursor was created with a default + * Charset + */ + public String getLargeVarChar(String columnName) { + LargeVarCharVector vector = (LargeVarCharVector) table.getVector(columnName); + return new String(vector.get(rowNumber), getDefaultCharacterSet()); + } + + /** + * Returns a String from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present in the Cursor and an IllegalArgumentException is thrown + * if it has a different type + * + * @param vectorName the name of the FieldVector holding the value + * @param charset the charset to use for decoding the bytes + */ + public String getLargeVarChar(String vectorName, Charset charset) { + LargeVarCharVector vector = (LargeVarCharVector) table.getVector(vectorName); + return new String(vector.get(rowNumber), charset); + } + + /** + * Returns a String from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalArgumentException is thrown if it has a different type + */ + public String getLargeVarChar(int columnIndex) { + LargeVarCharVector vector = (LargeVarCharVector) table.getVector(columnIndex); + return new String(vector.get(rowNumber), getDefaultCharacterSet()); + } + + /** + * Returns a String from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalArgumentException is thrown if it has a different type + * + * @param columnIndex the index of the FieldVector holding the value + * @param charset the charset to use for decoding the bytes + */ + public String getLargeVarChar(int columnIndex, Charset charset) { + LargeVarCharVector vector = (LargeVarCharVector) table.getVector(columnIndex); + return new String(vector.get(rowNumber), charset); + } + + // TODO: Implement getters for + // List & LargeList + // plus (for dealing with nulls?) + // all the object getters for things like TimeStampTz for Boxed return results (e.g. long v Long) + // plus ones using holders + + /** + * Returns true if there is at least one more non-deleted row in the table that has yet to be + * processed. + */ + @Override + public boolean hasNext() { + return nextRowSet || setNextObject(); + } + + /** + * Returns the next non-deleted row in the table. + * + * @throws NoSuchElementException if there are no more rows + */ + @Override + public Cursor next() { + if (!nextRowSet && !setNextObject()) { + throw new NoSuchElementException(); + } + nextRowSet = false; + return this; + } + + /** + * Set rowNumber to the next non-deleted row. If there are no more rows return false. Otherwise, + * return true. + */ + private boolean setNextObject() { + while (iterator.hasNext()) { + final int row = iterator.next(); + if (!rowIsDeleted(row)) { + rowNumber = row; + nextRowSet = true; + return true; + } + } + return false; + } + + /** + * Returns new internal iterator that processes every row, deleted or not. Users should use the + * wrapping next() and hasNext() methods rather than using this iterator directly, unless you want + * to see any deleted rows. + */ + private Iterator intIterator() { + return new Iterator() { + + @Override + public boolean hasNext() { + return rowNumber < table.getRowCount() - 1; + } + + @Override + public Integer next() { + rowNumber++; + return rowNumber; + } + }; + } + + public int getRowNumber() { + return rowNumber; + } + + private boolean rowIsDeleted(int rowNumber) { + return table.isRowDeleted(rowNumber); + } +} diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/Table.java b/java/vector/src/main/java/org/apache/arrow/vector/table/Table.java new file mode 100644 index 00000000000..5c2f2425e40 --- /dev/null +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/Table.java @@ -0,0 +1,187 @@ +/* + * 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.table; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +import org.apache.arrow.util.Preconditions; +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.VectorSchemaRoot; +import org.apache.arrow.vector.dictionary.DictionaryProvider; +import org.apache.arrow.vector.util.TransferPair; + +/** + * Table is an immutable tabular data structure. + * + *

See {@link VectorSchemaRoot} for batch processing use cases + */ +public class Table extends BaseTable implements Iterable { + + /** Constructs new instance containing each of the given vectors. */ + public Table(Iterable vectors) { + this(StreamSupport.stream(vectors.spliterator(), false).collect(Collectors.toList())); + } + + /** Constructs a new instance from vectors. */ + public static Table of(FieldVector... vectors) { + return new Table(Arrays.stream(vectors).collect(Collectors.toList())); + } + + /** + * Constructs a new instance with the number of rows set to the value count of the first + * FieldVector. + * + *

All vectors must have the same value count. Although this is not checked, inconsistent + * counts may lead to exceptions or other undefined behavior later. + * + * @param fieldVectors The data vectors (must be equal in size to fields. + */ + public Table(List fieldVectors) { + this(fieldVectors, fieldVectors.size() == 0 ? 0 : fieldVectors.get(0).getValueCount()); + } + + /** + * Constructs a new instance. + * + * @param fieldVectors The data vectors. + * @param rowCount The number of rows + */ + public Table(List fieldVectors, int rowCount) { + super(fieldVectors, rowCount, null); + } + + /** + * Constructs a new instance. + * + * @param fieldVectors The data vectors. + * @param rowCount The number of rows + * @param provider A dictionary provider. May be null if none of the vectors is dictionary encoded + */ + public Table(List fieldVectors, int rowCount, DictionaryProvider provider) { + super(fieldVectors, rowCount, provider); + } + + /* + */ + /** Constructs a new instance containing the children of parent but not the parent itself. */ + /* + + public Table(FieldVector parent) { + this(parent.getField().getChildren(), parent.getChildrenFromFields(), parent.getValueCount()); + } + */ + + /** + * Constructs a new instance containing the data from the argument. Vectors are shared between the + * Table and VectorSchemaRoot. Direct modification of those vectors is unsafe and should be + * avoided. + * + * @param vsr The VectorSchemaRoot providing data for this Table + */ + public Table(VectorSchemaRoot vsr) { + this(vsr.getFieldVectors(), vsr.getRowCount()); + vsr.clear(); + } + + /** + * Returns a new Table created by adding the given vector to the vectors in this Table. + * + * @param index field index + * @param vector vector to be added. + * @return out a new Table with vector added + */ + public Table addVector(int index, FieldVector vector) { + return new Table(insertVector(index, vector)); + } + + /** + * Returns a new Table created by removing the selected Vector from this Table. + * + * @param index field index + * @return out a new Table with vector removed + */ + public Table removeVector(int index) { + return new Table(extractVector(index)); + } + + /** + * Slice this table from desired index. Memory is NOT transferred from the vectors in this table + * to new vectors in the target table. This table is unchanged. + * + * @param index start position of the slice + * @return the sliced table + */ + public Table slice(int index) { + return slice(index, this.rowCount - index); + } + + /** + * Slice this table at desired index and length. Memory is NOT transferred from the vectors in + * this table to new vectors in the target table. This table is unchanged. + * + * @param index start position of the slice + * @param length length of the slice + * @return the sliced table + */ + public Table slice(int index, int length) { + Preconditions.checkArgument(index >= 0, "expecting non-negative index"); + Preconditions.checkArgument(length >= 0, "expecting non-negative length"); + Preconditions.checkArgument(index + length <= rowCount, "index + length should <= rowCount"); + + if (index == 0 && length == rowCount) { + return this; + } + + List sliceVectors = + fieldVectors.stream() + .map( + v -> { + TransferPair transferPair = v.getTransferPair(v.getAllocator()); + transferPair.splitAndTransfer(index, length); + return (FieldVector) transferPair.getTo(); + }) + .collect(Collectors.toList()); + + return new Table(sliceVectors); + } + + /** Returns a Cursor iterator for this Table. */ + @Override + public Iterator iterator() { + + return new Iterator() { + + private final Cursor row = new Cursor(Table.this); + + @Override + public Cursor next() { + row.next(); + return row; + } + + @Override + public boolean hasNext() { + return row.hasNext(); + } + }; + } +} diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java new file mode 100644 index 00000000000..fddd056e884 --- /dev/null +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java @@ -0,0 +1,252 @@ +/* + * 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.table; + +import static org.apache.arrow.vector.table.TestUtils.INT_VECTOR_NAME; +import static org.apache.arrow.vector.table.TestUtils.INT_VECTOR_NAME_1; +import static org.apache.arrow.vector.table.TestUtils.INT_VECTOR_NAME_2; +import static org.apache.arrow.vector.table.TestUtils.intPlusVarcharColumns; +import static org.apache.arrow.vector.table.TestUtils.twoIntColumns; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.IntVector; +import org.apache.arrow.vector.VarCharVector; +import org.apache.arrow.vector.VectorSchemaRoot; +import org.apache.arrow.vector.dictionary.Dictionary; +import org.apache.arrow.vector.dictionary.DictionaryProvider; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.DictionaryEncoding; +import org.apache.arrow.vector.types.pojo.FieldType; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class BaseTableTest { + + private BufferAllocator allocator; + + @BeforeEach + public void init() { + allocator = new RootAllocator(Long.MAX_VALUE); + } + + @Test + void getReaderByName() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + assertNotNull(t.getReader(INT_VECTOR_NAME_1)); + } + } + + @Test + void getReaderByIndex() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + assertNotNull(t.getReader(0)); + } + } + + @Test + void getReaderByField() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + assertNotNull(t.getReader(t.getField(INT_VECTOR_NAME_1))); + } + } + + @Test + void getSchema() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + assertNotNull(t.getSchema()); + assertEquals(2, t.getSchema().getFields().size()); + } + } + + @Test + void insertVector() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + ArrowType intArrowType = new ArrowType.Int(32, true); + FieldType intFieldType = new FieldType(true, intArrowType, null); + IntVector v3 = new IntVector("3", intFieldType, allocator); + List revisedVectors = t.insertVector(2, v3); + assertEquals(3, revisedVectors.size()); + assertEquals(v3, revisedVectors.get(2)); + } + } + + @Test + void insertVectorFirstPosition() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + ArrowType intArrowType = new ArrowType.Int(32, true); + FieldType intFieldType = new FieldType(true, intArrowType, null); + IntVector v3 = new IntVector("3", intFieldType, allocator); + List revisedVectors = t.insertVector(0, v3); + assertEquals(3, revisedVectors.size()); + assertEquals(v3, revisedVectors.get(0)); + } + } + + @Test + void extractVector() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + List revisedVectors = t.extractVector(0); + assertEquals(2, t.getVectorCount()); // vector not removed from table yet + assertEquals(1, revisedVectors.size()); + } + } + + @Test + void close() { + IntVector v = new IntVector(INT_VECTOR_NAME, allocator); + v.setSafe(0, 132); + List vectors = new ArrayList<>(); + vectors.add(v); + v.setValueCount(1); + try (Table t = new Table(vectors)) { + t.close(); + for (FieldVector fieldVector : t.fieldVectors) { + assertEquals(0, fieldVector.getValueCount()); + } + } + } + + @Test + void getRowCount() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + // TODO: handle setting rowcount on Table construction + assertEquals(2, t.getRowCount()); + } + } + + @Test + void toVectorSchemaRoot() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + assertNotNull(t.getVector(INT_VECTOR_NAME_1)); + assertNotNull(t.getVector(INT_VECTOR_NAME_2)); + VectorSchemaRoot vsr = t.toVectorSchemaRoot(); + assertNotNull(vsr.getVector(INT_VECTOR_NAME_1)); + assertNotNull(vsr.getVector(INT_VECTOR_NAME_2)); + assertEquals( + t.getSchema().findField(INT_VECTOR_NAME_1), vsr.getSchema().findField(INT_VECTOR_NAME_1)); + } + } + + @Test + void getVector() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + assertNotNull(t.getVector(0)); + } + } + + @Test + void testGetVector() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + assertNotNull(t.getVector(INT_VECTOR_NAME_1)); + assertNull(t.getVector("foobar")); + } + } + + @Test + void immutableCursor() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + assertNotNull(t.immutableCursor()); + } + } + + @Test + void contentToTsvString() { + IntVector v = new IntVector(INT_VECTOR_NAME, allocator); + v.setSafe(0, 1); + v.setSafe(1, 2); + v.setSafe(2, 3); + v.setValueCount(3); + + try (Table t = Table.of(v)) { + assertEquals(3, t.rowCount); + List values = new ArrayList<>(); + for (Cursor r : t) { + values.add(r.getInt(INT_VECTOR_NAME)); + } + assertEquals(3, values.size()); + List intList = new ArrayList<>(); + intList.add(1); + intList.add(2); + intList.add(3); + assertTrue(values.containsAll(intList)); + String printed = "intCol\n" + "1\n" + "2\n" + "3\n"; + assertEquals(printed, t.contentToTSVString()); + } + } + + @Test + void isDeletedRow() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + assertFalse(t.isRowDeleted(0)); + assertFalse(t.isRowDeleted(1)); + } + } + + @Test + void testEncode() { + List vectorList = intPlusVarcharColumns(allocator); + VarCharVector original = (VarCharVector) vectorList.get(1); + DictionaryProvider provider = getDictionary(); + try (Table t = new Table(vectorList, vectorList.get(0).getValueCount(), provider)) { + IntVector v = (IntVector) t.encode(original.getName(), 1L); + assertNotNull(v); + assertEquals(0, v.get(0)); + assertEquals(1, v.get(1)); + } + } + + private DictionaryProvider getDictionary() { + + DictionaryProvider.MapDictionaryProvider provider = + new DictionaryProvider.MapDictionaryProvider(); + DictionaryEncoding encoding = new DictionaryEncoding(1L, false, null); + + VarCharVector dictionaryVector = new VarCharVector("dictionary", allocator); + dictionaryVector.allocateNew(2); + dictionaryVector.set(0, "one".getBytes()); + dictionaryVector.set(1, "two".getBytes()); + dictionaryVector.setValueCount(2); + + Dictionary dictionary = new Dictionary(dictionaryVector, encoding); + provider.put(dictionary); + return provider; + } +} diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/CursorTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/CursorTest.java new file mode 100644 index 00000000000..0506ef0d710 --- /dev/null +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/CursorTest.java @@ -0,0 +1,286 @@ +/* + * 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.table; + +import static org.apache.arrow.vector.table.TestUtils.BIGINT_INT_MAP_VECTOR_NAME; +import static org.apache.arrow.vector.table.TestUtils.INT_LIST_VECTOR_NAME; +import static org.apache.arrow.vector.table.TestUtils.INT_VECTOR_NAME_1; +import static org.apache.arrow.vector.table.TestUtils.STRUCT_VECTOR_NAME; +import static org.apache.arrow.vector.table.TestUtils.UNION_VECTOR_NAME; +import static org.apache.arrow.vector.table.TestUtils.fixedWidthVectors; +import static org.apache.arrow.vector.table.TestUtils.simpleDenseUnionVector; +import static org.apache.arrow.vector.table.TestUtils.simpleListVector; +import static org.apache.arrow.vector.table.TestUtils.simpleMapVector; +import static org.apache.arrow.vector.table.TestUtils.simpleStructVector; +import static org.apache.arrow.vector.table.TestUtils.simpleUnionVector; +import static org.apache.arrow.vector.table.TestUtils.twoIntColumns; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.nio.charset.StandardCharsets; +import java.util.List; + +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.VectorSchemaRoot; +import org.apache.arrow.vector.complex.DenseUnionVector; +import org.apache.arrow.vector.complex.ListVector; +import org.apache.arrow.vector.complex.MapVector; +import org.apache.arrow.vector.complex.StructVector; +import org.apache.arrow.vector.complex.UnionVector; +import org.apache.arrow.vector.util.JsonStringHashMap; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class CursorTest { + + private BufferAllocator allocator; + + @BeforeEach + public void init() { + allocator = new RootAllocator(Long.MAX_VALUE); + } + + @AfterEach + public void terminate() { + allocator.close(); + } + + @Test + void constructor() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + Cursor c = t.immutableCursor(StandardCharsets.US_ASCII); + assertEquals(StandardCharsets.US_ASCII, c.getDefaultCharacterSet()); + } + } + + @Test + void at() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + Cursor c = t.immutableCursor(); + assertEquals(c.getRowNumber(), -1); + c.setPosition(1); + assertEquals(c.getRowNumber(), 1); + } + } + + @Test + void getIntByVectorIndex() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + Cursor c = t.immutableCursor(); + c.setPosition(1); + assertEquals(2, c.getInt(0)); + } + } + + @Test + void getIntByVectorName() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + Cursor c = t.immutableCursor(); + c.setPosition(1); + assertEquals(2, c.getInt(INT_VECTOR_NAME_1)); + } + } + + @Test + void hasNext() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + Cursor c = t.immutableCursor(); + assertTrue(c.hasNext()); + c.setPosition(1); + assertFalse(c.hasNext()); + } + } + + @Test + void next() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + Cursor c = t.immutableCursor(); + c.setPosition(0); + c.next(); + assertEquals(1, c.getRowNumber()); + } + } + + @Test + void isNull() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + Cursor c = t.immutableCursor(); + c.setPosition(1); + assertFalse(c.isNull(0)); + } + } + + @Test + void isNullByFieldName() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + Cursor c = t.immutableCursor(); + c.setPosition(1); + assertFalse(c.isNull(INT_VECTOR_NAME_1)); + } + } + + @Test + void fixedWidthVectorTest() { + List vectorList = fixedWidthVectors(allocator, 2); + try (Table t = new Table(vectorList)) { + Cursor c = t.immutableCursor(); + c.setPosition(1); + assertFalse(c.isNull("bigInt_vector")); + assertEquals(c.getInt("int_vector"), c.getInt(0)); + assertEquals(c.getBigInt("bigInt_vector"), c.getBigInt(1)); + assertEquals(c.getSmallInt("smallInt_vector"), c.getSmallInt(2)); + assertEquals(c.getTinyInt("tinyInt_vector"), c.getTinyInt(3)); + + // TODO: Uncomment these when GenerateSampleData supports UInts + // assertEquals(c.getUInt1("uInt1_vector"), c.getUInt1(0)); + // assertEquals(c.getUInt2("uInt2_vector"), c.getUInt2(1)); + // assertEquals(c.getUInt4("uInt4_vector"), c.getUInt4(2)); + // assertEquals(c.getUInt8("uInt8_vector"), c.getUInt8(3)); + + assertEquals(c.getFloat4("float4_vector"), c.getFloat4(8)); + assertEquals(c.getFloat8("float8_vector"), c.getFloat8(9)); + + assertEquals(c.getTimeSec("timeSec_vector"), c.getTimeSec(10)); + assertEquals(c.getTimeMilli("timeMilli_vector"), c.getTimeMilli(11)); + assertEquals(c.getTimeMicro("timeMicro_vector"), c.getTimeMicro(12)); + assertEquals(c.getTimeNano("timeNano_vector"), c.getTimeNano(13)); + + assertEquals(c.getTimeStampSec("timeStampSec_vector"), c.getTimeStampSec(14)); + assertEquals(c.getTimeStampMilli("timeStampMilli_vector"), c.getTimeStampMilli(15)); + assertEquals(c.getTimeStampMicro("timeStampMicro_vector"), c.getTimeStampMicro(16)); + assertEquals(c.getTimeStampNano("timeStampNano_vector"), c.getTimeStampNano(17)); + } + } + + @Test + void testSimpleListVector1() { + try (ListVector listVector = simpleListVector(allocator); + VectorSchemaRoot vectorSchemaRoot = VectorSchemaRoot.of(listVector); + Table table = new Table(vectorSchemaRoot)) { + for (Cursor c : table) { + @SuppressWarnings("unchecked") + List list = (List) c.getList(INT_LIST_VECTOR_NAME); + assertEquals(10, list.size()); + } + } + } + + @Test + void testSimpleListVector2() { + try (ListVector listVector = simpleListVector(allocator); + VectorSchemaRoot vectorSchemaRoot = VectorSchemaRoot.of(listVector); + Table table = new Table(vectorSchemaRoot)) { + for (Cursor c : table) { + @SuppressWarnings("unchecked") + List list = (List) c.getList(0); + assertEquals(10, list.size()); + } + } + } + + @Test + void testSimpleStructVector1() { + try (StructVector structVector = simpleStructVector(allocator); + VectorSchemaRoot vectorSchemaRoot = VectorSchemaRoot.of(structVector); + Table table = new Table(vectorSchemaRoot)) { + System.out.println(table.contentToTSVString()); + for (Cursor c : table) { + @SuppressWarnings("unchecked") + JsonStringHashMap struct = + (JsonStringHashMap) c.getStruct(STRUCT_VECTOR_NAME); + int a = (int) struct.get("struct_int_child"); + double b = (double) struct.get("struct_flt_child"); + assertNotNull(struct); + assertTrue(a >= 0); + assertTrue(b <= a, String.format("a = %s and b = %s", a, b)); + } + } + } + + @Test + void testSimpleUnionVector() { + try (UnionVector unionVector = simpleUnionVector(allocator); + VectorSchemaRoot vsr = VectorSchemaRoot.of(unionVector); + Table table = new Table(vsr)) { + Cursor c = table.immutableCursor(); + c.setPosition(0); + Object object0 = c.getUnion(UNION_VECTOR_NAME); + c.setPosition(1); + assertNull(c.getUnion(UNION_VECTOR_NAME)); + c.setPosition(2); + Object object2 = c.getUnion(UNION_VECTOR_NAME); + assertEquals(100, object0); + assertEquals(100, object2); + } + } + + @Test + void testSimpleDenseUnionVector() { + try (DenseUnionVector unionVector = simpleDenseUnionVector(allocator); + VectorSchemaRoot vsr = VectorSchemaRoot.of(unionVector); + Table table = new Table(vsr)) { + Cursor c = table.immutableCursor(); + c.setPosition(0); + Object object0 = c.getDenseUnion(UNION_VECTOR_NAME); + c.setPosition(1); + assertNull(c.getDenseUnion(UNION_VECTOR_NAME)); + c.setPosition(2); + Object object2 = c.getDenseUnion(UNION_VECTOR_NAME); + assertEquals(100, object0); + assertEquals(100, object2); + } + } + + @Test + void testSimpleMapVector1() { + try (MapVector mapVector = simpleMapVector(allocator); + Table table = Table.of(mapVector)) { + + int i = 1; + for (Cursor c : table) { + @SuppressWarnings("unchecked") + List> list = + (List>) c.getMap(BIGINT_INT_MAP_VECTOR_NAME); + if (list != null && !list.isEmpty()) { + assertEquals(i, list.size()); + for (JsonStringHashMap sv : list) { + assertEquals(2, sv.size()); + Long o1 = (Long) sv.get("key"); + Integer o2 = (Integer) sv.get("value"); + assertEquals(o1, o2.longValue()); + } + } + i++; + } + } + } +} diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/TableTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/TableTest.java new file mode 100644 index 00000000000..13ed1e59b4a --- /dev/null +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/TableTest.java @@ -0,0 +1,228 @@ +/* + * 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.table; + +import static org.apache.arrow.vector.table.TestUtils.INT_VECTOR_NAME_1; +import static org.apache.arrow.vector.table.TestUtils.twoIntColumns; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Iterator; +import java.util.List; + +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.IntVector; +import org.apache.arrow.vector.VectorSchemaRoot; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.arrow.vector.types.pojo.FieldType; +import org.apache.arrow.vector.types.pojo.Schema; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class TableTest { + + private final ArrowType intArrowType = new ArrowType.Int(32, true); + private final FieldType intFieldType = new FieldType(true, intArrowType, null); + + private BufferAllocator allocator; + + @BeforeEach + public void init() { + allocator = new RootAllocator(Long.MAX_VALUE); + } + + @Test + void of() { + List vectorList = twoIntColumns(allocator); + try (Table t = Table.of(vectorList.toArray(new FieldVector[2]))) { + Cursor c = t.immutableCursor(); + assertEquals(2, t.getRowCount()); + assertEquals(2, t.getVectorCount()); + IntVector intVector1 = (IntVector) vectorList.get(0); + assertEquals(INT_VECTOR_NAME_1, intVector1.getName()); + c.setPosition(0); + + // Now test changes to the first vector + // first Table value is 1 + assertEquals(1, c.getInt(INT_VECTOR_NAME_1)); + + // original vector is updated to set first value to 44 + intVector1.setSafe(0, 44); + assertEquals(44, intVector1.get(0)); + + // first Table value is still 1 for the zeroth vector + assertEquals(1, c.getInt(0)); + } + } + + @Test + void constructor() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList, 2)) { + assertEquals(2, t.getRowCount()); + assertEquals(2, t.getVectorCount()); + Cursor c = t.immutableCursor(); + IntVector intVector1 = (IntVector) vectorList.get(0); + c.setPosition(0); + + // Now test changes to the first vector + // first Table value is 1 + assertEquals(1, c.getInt(INT_VECTOR_NAME_1)); + + // original vector is updated to set first value to 44 + intVector1.setSafe(0, 44); + assertEquals(44, intVector1.get(0)); + assertEquals(44, ((IntVector) vectorList.get(0)).get(0)); + + // first Table value is still 1 for the zeroth vector + assertEquals(1, c.getInt(INT_VECTOR_NAME_1)); + } + } + + @Test + void addVector() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + IntVector v3 = new IntVector("3", intFieldType, allocator); + Table t2 = t.addVector(2, v3); + assertEquals(3, t2.fieldVectors.size()); + assertTrue(t2.getVector("3").isNull(0)); + assertTrue(t2.getVector("3").isNull(1)); + t2.close(); + } + } + + @Test + void removeVector() { + List vectorList = twoIntColumns(allocator); + IntVector v2 = (IntVector) vectorList.get(1); + int val1 = v2.get(0); + int val2 = v2.get(1); + try (Table t = new Table(vectorList)) { + + Table t2 = t.removeVector(0); + assertEquals(1, t2.fieldVectors.size()); + assertEquals(val1, ((IntVector) t2.getVector(0)).get(0)); + assertEquals(val2, ((IntVector) t2.getVector(0)).get(1)); + } + } + + /** Tests table iterator in enhanced for loop. */ + @Test + void iterator1() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + Iterator iterator = t.iterator(); + assertNotNull(iterator); + assertTrue(iterator.hasNext()); + int sum = 0; + for (Cursor row : t) { + sum += row.getInt(0); + } + assertEquals(3, sum); + } + } + + /** Tests explicit iterator. */ + @SuppressWarnings("WhileLoopReplaceableByForEach") + @Test + void iterator2() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + Iterator iterator = t.iterator(); + assertNotNull(iterator); + assertTrue(iterator.hasNext()); + int sum = 0; + Iterator it = t.iterator(); + while (it.hasNext()) { + Cursor row = it.next(); + sum += row.getInt(0); + } + assertEquals(3, sum); + } + } + + /** + * Tests a slice operation where no length is provided, so the range extends to the end of the + * table. + */ + @Test + void sliceToEnd() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + Table slice = t.slice(1); + assertEquals(1, slice.rowCount); + assertEquals(2, t.rowCount); // memory is copied for slice, not transferred + slice.close(); + } + } + + /** Tests a slice operation with a given length parameter. */ + @Test + void sliceRange() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + Table slice = t.slice(1, 1); + assertEquals(1, slice.rowCount); + assertEquals(2, t.rowCount); // memory is copied for slice, not transferred + slice.close(); + } + } + + /** + * Tests creation of a table from a VectorSchemaRoot. + * + *

Also tests that updates to the source Vectors do not impact the values in the Table + */ + @Test + void constructFromVsr() { + List vectorList = twoIntColumns(allocator); + try (VectorSchemaRoot vsr = new VectorSchemaRoot(vectorList)) { + Table t = new Table(vsr); + Cursor c = t.immutableCursor(); + assertEquals(2, t.rowCount); + assertEquals(0, vsr.getRowCount()); // memory is copied for slice, not transferred + IntVector intVector1 = (IntVector) vectorList.get(0); + c.setPosition(0); + + // Now test changes to the first vector + // first Table value is 1 + assertEquals(1, c.getInt(INT_VECTOR_NAME_1)); + + // original vector is updated to set first value to 44 + intVector1.setSafe(0, 44); + assertEquals(44, intVector1.get(0)); + assertEquals(44, ((IntVector) vsr.getVector(0)).get(0)); + + // first Table value is still 1 for the zeroth vector + assertEquals(1, c.getInt(INT_VECTOR_NAME_1)); + + // TEST FIELDS // + Schema schema = t.schema; + Field f1 = t.getField(INT_VECTOR_NAME_1); + FieldVector fv1 = vectorList.get(0); + assertEquals(f1, fv1.getField()); + assertEquals(f1, schema.findField(INT_VECTOR_NAME_1)); + t.close(); + } + } +} diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java b/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java new file mode 100644 index 00000000000..875e97c61fc --- /dev/null +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java @@ -0,0 +1,280 @@ +/* + * 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.table; + +import static org.apache.arrow.vector.complex.BaseRepeatedValueVector.OFFSET_WIDTH; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.vector.BigIntVector; +import org.apache.arrow.vector.BitVectorHelper; +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.Float4Vector; +import org.apache.arrow.vector.Float8Vector; +import org.apache.arrow.vector.GenerateSampleData; +import org.apache.arrow.vector.IntVector; +import org.apache.arrow.vector.SmallIntVector; +import org.apache.arrow.vector.TimeMicroVector; +import org.apache.arrow.vector.TimeMilliVector; +import org.apache.arrow.vector.TimeNanoVector; +import org.apache.arrow.vector.TimeSecVector; +import org.apache.arrow.vector.TimeStampMicroVector; +import org.apache.arrow.vector.TimeStampMilliVector; +import org.apache.arrow.vector.TimeStampNanoVector; +import org.apache.arrow.vector.TimeStampSecVector; +import org.apache.arrow.vector.TinyIntVector; +import org.apache.arrow.vector.UInt1Vector; +import org.apache.arrow.vector.UInt2Vector; +import org.apache.arrow.vector.UInt4Vector; +import org.apache.arrow.vector.UInt8Vector; +import org.apache.arrow.vector.VarCharVector; +import org.apache.arrow.vector.complex.DenseUnionVector; +import org.apache.arrow.vector.complex.ListVector; +import org.apache.arrow.vector.complex.MapVector; +import org.apache.arrow.vector.complex.StructVector; +import org.apache.arrow.vector.complex.UnionVector; +import org.apache.arrow.vector.complex.impl.NullableStructWriter; +import org.apache.arrow.vector.complex.impl.UnionMapWriter; +import org.apache.arrow.vector.complex.writer.Float8Writer; +import org.apache.arrow.vector.complex.writer.IntWriter; +import org.apache.arrow.vector.holders.NullableUInt4Holder; +import org.apache.arrow.vector.types.Types; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.arrow.vector.types.pojo.FieldType; +import org.junit.platform.commons.util.Preconditions; + +public class TestUtils { + + public static final String INT_VECTOR_NAME = "intCol"; + public static final String INT_VECTOR_NAME_1 = "intCol1"; + public static final String VARCHAR_VECTOR_NAME_1 = "varcharCol1"; + public static final String INT_VECTOR_NAME_2 = "intCol2"; + public static final String INT_LIST_VECTOR_NAME = "int list vector"; + public static final String BIGINT_INT_MAP_VECTOR_NAME = "bigint-int map vector"; + public static final String STRUCT_VECTOR_NAME = "struct_vector"; + public static final String UNION_VECTOR_NAME = "union_vector"; + + /** + * Returns a list of two IntVectors to be used to instantiate Tables for testing. Each IntVector + * has two values set. + */ + static List twoIntColumns(BufferAllocator allocator) { + List vectorList = new ArrayList<>(); + Preconditions.condition(allocator != null, "allocator is null"); + IntVector v1 = new IntVector(INT_VECTOR_NAME_1, allocator); + v1.allocateNew(2); + v1.set(0, 1); + v1.set(1, 2); + v1.setValueCount(2); + IntVector v2 = new IntVector(INT_VECTOR_NAME_2, allocator); + v2.allocateNew(2); + v2.set(0, 3); + v2.set(1, 4); + v2.setValueCount(2); + vectorList.add(v1); + vectorList.add(v2); + return vectorList; + } + + /** + * Returns a list of two FieldVectors to be used to instantiate Tables for testing. The first + * vector is an IntVector and the second is a VarCharVector. Each vector has two values set. + */ + static List intPlusVarcharColumns(BufferAllocator allocator) { + List vectorList = new ArrayList<>(); + Preconditions.condition(allocator != null, "allocator is null"); + IntVector v1 = new IntVector(INT_VECTOR_NAME_1, allocator); + v1.allocateNew(2); + v1.set(0, 1); + v1.set(1, 2); + v1.setValueCount(2); + VarCharVector v2 = new VarCharVector(VARCHAR_VECTOR_NAME_1, allocator); + v2.allocateNew(2); + v2.set(0, "one".getBytes()); + v2.set(1, "two".getBytes()); + v2.setValueCount(2); + vectorList.add(v1); + vectorList.add(v2); + return vectorList; + } + + static List fixedWidthVectors(BufferAllocator allocator, int rowCount) { + List vectors = new ArrayList<>(); + numericVectors(vectors, allocator, rowCount); + return simpleTemporalVectors(vectors, allocator, rowCount); + } + + static List numericVectors( + List vectors, BufferAllocator allocator, int rowCount) { + vectors.add(new IntVector("int_vector", allocator)); + vectors.add(new BigIntVector("bigInt_vector", allocator)); + vectors.add(new SmallIntVector("smallInt_vector", allocator)); + vectors.add(new TinyIntVector("tinyInt_vector", allocator)); + vectors.add(new UInt1Vector("uInt1_vector", allocator)); + vectors.add(new UInt2Vector("uInt2_vector", allocator)); + vectors.add(new UInt4Vector("uInt4_vector", allocator)); + vectors.add(new UInt8Vector("uInt8_vector", allocator)); + vectors.add(new Float4Vector("float4_vector", allocator)); + vectors.add(new Float8Vector("float8_vector", allocator)); + vectors.forEach(vec -> GenerateSampleData.generateTestData(vec, rowCount)); + return vectors; + } + + static List numericVectors(BufferAllocator allocator, int rowCount) { + List vectors = new ArrayList<>(); + return numericVectors(vectors, allocator, rowCount); + } + + static List simpleTemporalVectors( + List vectors, BufferAllocator allocator, int rowCount) { + vectors.add(new TimeSecVector("timeSec_vector", allocator)); + vectors.add(new TimeMilliVector("timeMilli_vector", allocator)); + vectors.add(new TimeMicroVector("timeMicro_vector", allocator)); + vectors.add(new TimeNanoVector("timeNano_vector", allocator)); + + vectors.add(new TimeStampSecVector("timeStampSec_vector", allocator)); + vectors.add(new TimeStampMilliVector("timeStampMilli_vector", allocator)); + vectors.add(new TimeStampMicroVector("timeStampMicro_vector", allocator)); + vectors.add(new TimeStampNanoVector("timeStampNano_vector", allocator)); + + vectors.forEach(vec -> GenerateSampleData.generateTestData(vec, rowCount)); + return vectors; + } + + static List simpleTemporalVectors(BufferAllocator allocator, int rowCount) { + List vectors = new ArrayList<>(); + return simpleTemporalVectors(vectors, allocator, rowCount); + } + + /** Returns a list vector of ints. */ + static ListVector simpleListVector(BufferAllocator allocator) { + ListVector listVector = ListVector.empty(INT_LIST_VECTOR_NAME, allocator); + final int innerCount = 80; // total number of values + final int outerCount = 8; // total number of values in the list vector itself + final int listLength = innerCount / outerCount; // length of an individual list + + Types.MinorType type = Types.MinorType.INT; + listVector.addOrGetVector(FieldType.nullable(type.getType())); + + listVector.allocateNew(); + IntVector dataVector = (IntVector) listVector.getDataVector(); + + for (int i = 0; i < innerCount; i++) { + dataVector.set(i, i); + } + dataVector.setValueCount(innerCount); + + for (int i = 0; i < outerCount; i++) { + BitVectorHelper.setBit(listVector.getValidityBuffer(), i); + listVector.getOffsetBuffer().setInt(i * OFFSET_WIDTH, i * listLength); + listVector.getOffsetBuffer().setInt((i + 1) * OFFSET_WIDTH, (i + 1) * listLength); + } + listVector.setLastSet(outerCount - 1); + listVector.setValueCount(outerCount); + + return listVector; + } + + static StructVector simpleStructVector(BufferAllocator allocator) { + final String INT_COL = "struct_int_child"; + final String FLT_COL = "struct_flt_child"; + StructVector structVector = StructVector.empty(STRUCT_VECTOR_NAME, allocator); + final int size = 6; // number of structs + + NullableStructWriter structWriter = structVector.getWriter(); + structVector.addOrGet( + INT_COL, FieldType.nullable(Types.MinorType.INT.getType()), IntVector.class); + structVector.addOrGet( + FLT_COL, FieldType.nullable(Types.MinorType.INT.getType()), IntVector.class); + structVector.allocateNew(); + IntWriter intWriter = structWriter.integer(INT_COL); + Float8Writer float8Writer = structWriter.float8(FLT_COL); + + for (int i = 0; i < size; i++) { + structWriter.setPosition(i); + structWriter.start(); + intWriter.writeInt(i); + float8Writer.writeFloat8(i * .1); + structWriter.end(); + } + + structWriter.setValueCount(size); + + return structVector; + } + + /** Returns a MapVector of ints to doubles. */ + static MapVector simpleMapVector(BufferAllocator allocator) { + MapVector mapVector = MapVector.empty(BIGINT_INT_MAP_VECTOR_NAME, allocator, false); + mapVector.allocateNew(); + int count = 5; + UnionMapWriter mapWriter = mapVector.getWriter(); + for (int i = 0; i < count; i++) { + mapWriter.startMap(); + for (int j = 0; j < i + 1; j++) { + mapWriter.startEntry(); + mapWriter.key().bigInt().writeBigInt(j); + mapWriter.value().integer().writeInt(j); + mapWriter.endEntry(); + } + mapWriter.endMap(); + } + mapWriter.setValueCount(count); + return mapVector; + } + + /** Returns a UnionVector. */ + static UnionVector simpleUnionVector(BufferAllocator allocator) { + final NullableUInt4Holder uInt4Holder = new NullableUInt4Holder(); + uInt4Holder.value = 100; + uInt4Holder.isSet = 1; + + UnionVector unionVector = new UnionVector(UNION_VECTOR_NAME, allocator, null, null); + unionVector.allocateNew(); + + // write some data + unionVector.setType(0, Types.MinorType.UINT4); + unionVector.setSafe(0, uInt4Holder); + unionVector.setType(2, Types.MinorType.UINT4); + unionVector.setSafe(2, uInt4Holder); + unionVector.setValueCount(4); + return unionVector; + } + + /** Returns a DenseUnionVector. */ + static DenseUnionVector simpleDenseUnionVector(BufferAllocator allocator) { + final NullableUInt4Holder uInt4Holder = new NullableUInt4Holder(); + uInt4Holder.value = 100; + uInt4Holder.isSet = 1; + + DenseUnionVector unionVector = new DenseUnionVector(UNION_VECTOR_NAME, allocator, null, null); + unionVector.allocateNew(); + + // write some data + byte uint4TypeId = + unionVector.registerNewTypeId(Field.nullable("", Types.MinorType.UINT4.getType())); + unionVector.setTypeId(0, uint4TypeId); + unionVector.setSafe(0, uInt4Holder); + unionVector.setTypeId(2, uint4TypeId); + unionVector.setSafe(2, uInt4Holder); + unionVector.setValueCount(4); + return unionVector; + } +} From e64843ce26ed78a912bde4eea640b5d82ccbf96a Mon Sep 17 00:00:00 2001 From: Larry White Date: Thu, 29 Sep 2022 14:00:20 -0400 Subject: [PATCH 02/40] Initial commit of Table support --- .../main/java/org/apache/arrow/c/Data.java | 43 ++- .../table/{BaseCursor.java => BaseRow.java} | 12 +- .../apache/arrow/vector/table/BaseTable.java | 12 +- .../org/apache/arrow/vector/table/README.md | 339 ++++++++++++++++++ .../vector/table/{Cursor.java => Row.java} | 74 ++-- .../org/apache/arrow/vector/table/Table.java | 12 +- .../arrow/vector/table/package-info.java | 25 ++ .../arrow/vector/table/BaseTableTest.java | 2 +- .../table/{CursorTest.java => RowTest.java} | 32 +- .../apache/arrow/vector/table/TableTest.java | 16 +- .../apache/arrow/vector/table/TestUtils.java | 3 - 11 files changed, 485 insertions(+), 85 deletions(-) rename java/vector/src/main/java/org/apache/arrow/vector/table/{BaseCursor.java => BaseRow.java} (87%) create mode 100644 java/vector/src/main/java/org/apache/arrow/vector/table/README.md rename java/vector/src/main/java/org/apache/arrow/vector/table/{Cursor.java => Row.java} (97%) create mode 100644 java/vector/src/main/java/org/apache/arrow/vector/table/package-info.java rename java/vector/src/test/java/org/apache/arrow/vector/table/{CursorTest.java => RowTest.java} (94%) diff --git a/java/c/src/main/java/org/apache/arrow/c/Data.java b/java/c/src/main/java/org/apache/arrow/c/Data.java index 9ee5a6c757c..b931959d86b 100644 --- a/java/c/src/main/java/org/apache/arrow/c/Data.java +++ b/java/c/src/main/java/org/apache/arrow/c/Data.java @@ -28,6 +28,7 @@ import org.apache.arrow.vector.dictionary.DictionaryProvider; import org.apache.arrow.vector.ipc.ArrowReader; import org.apache.arrow.vector.ipc.message.ArrowRecordBatch; +import org.apache.arrow.vector.table.Table; import org.apache.arrow.vector.types.pojo.ArrowType; import org.apache.arrow.vector.types.pojo.ArrowType.ArrowTypeID; import org.apache.arrow.vector.types.pojo.Field; @@ -114,6 +115,44 @@ public static void exportVector(BufferAllocator allocator, FieldVector vector, D exporter.export(out, vector, provider); } + /** + * Export the current contents of a Java Table using the C data + * interface format. + *

+ * The table is exported as if it were a struct array. The + * resulting ArrowArray struct keeps the record batch data and buffers alive + * until its release callback is called by the consumer. + * + * @param allocator Buffer allocator for allocating C data interface fields + * @param table Table to export + * @param provider Dictionary provider for dictionary encoded vectors + * (optional) + * @param out C struct where to export the record batch + */ + public static void exportTable(BufferAllocator allocator, Table table, + DictionaryProvider provider, ArrowArray out) { + exportTable(allocator, table, provider, out, null); + } + + /** + * Export the current contents of a Java Table using the C data interface format. + *

+ * The table is exported as if it were a struct array. The + * resulting ArrowArray struct keeps the record batch data and buffers alive + * until its release callback is called by the consumer. + * + * @param allocator Buffer allocator for allocating C data interface fields + * @param table Table to export + * @param provider Dictionary provider for dictionary encoded vectors + * (optional) + * @param out C struct where to export the record batch + * @param outSchema C struct where to export the record batch schema (optional) + */ + public static void exportTable(BufferAllocator allocator, Table table, + DictionaryProvider provider, ArrowArray out, ArrowSchema outSchema) { + exportVectorSchemaRoot(allocator, table.toVectorSchemaRoot(), provider, out, outSchema); + } + /** * Export the current contents of a Java VectorSchemaRoot using the C data * interface format. @@ -121,7 +160,7 @@ public static void exportVector(BufferAllocator allocator, FieldVector vector, D * The vector schema root is exported as if it were a struct array. The * resulting ArrowArray struct keeps the record batch data and buffers alive * until its release callback is called by the consumer. - * + * * @param allocator Buffer allocator for allocating C data interface fields * @param vsr Vector schema root to export * @param provider Dictionary provider for dictionary encoded vectors @@ -129,7 +168,7 @@ public static void exportVector(BufferAllocator allocator, FieldVector vector, D * @param out C struct where to export the record batch */ public static void exportVectorSchemaRoot(BufferAllocator allocator, VectorSchemaRoot vsr, - DictionaryProvider provider, ArrowArray out) { + DictionaryProvider provider, ArrowArray out) { exportVectorSchemaRoot(allocator, vsr, provider, out, null); } diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/BaseCursor.java b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseRow.java similarity index 87% rename from java/vector/src/main/java/org/apache/arrow/vector/table/BaseCursor.java rename to java/vector/src/main/java/org/apache/arrow/vector/table/BaseRow.java index 05317eb2ad4..ffaab56e6b3 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/BaseCursor.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseRow.java @@ -23,7 +23,7 @@ /** * Provides row based access to the data held by a {@link Table}. */ -public abstract class BaseCursor { +public abstract class BaseRow { /** The table we're enumerating. */ protected final BaseTable table; @@ -38,22 +38,22 @@ public abstract class BaseCursor { private Charset defaultCharacterSet = StandardCharsets.UTF_8; /** - * Constructs a new BaseCursor backed by the given table. + * Constructs a new BaseRow backed by the given table. * * @param table the table that this MutableCursor object represents */ - public BaseCursor(BaseTable table) { + public BaseRow(BaseTable table) { this.table = table; } /** - * Constructs a new BaseCursor backed by the given table. + * Constructs a new BaseRow backed by the given table. * * @param table the table that this cursor represents * @param charset the standard charset for decoding bytes into strings. Note: This can be * overridden for individual columns. */ - public BaseCursor(BaseTable table, Charset charset) { + public BaseRow(BaseTable table, Charset charset) { this.table = table; this.defaultCharacterSet = charset; } @@ -61,7 +61,7 @@ public BaseCursor(BaseTable table, Charset charset) { /** * Resets the row index to -1 and returns this object. */ - BaseCursor resetPosition() { + BaseRow resetPosition() { rowNumber = -1; return this; } diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java index 6fd4b126b15..c0a046da382 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java @@ -265,21 +265,21 @@ FieldVector getVector(int columnIndex) { } /** - * Returns an immutable Cursor object holding a reference to this table. The default character + * Returns an immutable Row object holding a reference to this table. The default character * encoding used by the cursor to decode Strings will be StandardCharsets.UTF_8. */ - public Cursor immutableCursor() { - return new Cursor(this); + public Row immutableCursor() { + return new Row(this); } /** - * Returns an immutable Cursor object holding a reference to this table. + * Returns an immutable Row object holding a reference to this table. * * @param defaultCharset The default character encoding used by the cursor to decode Strings. It * can be overridden for individual vectors in the get() method */ - public Cursor immutableCursor(Charset defaultCharset) { - return new Cursor(this, defaultCharset); + public Row immutableCursor(Charset defaultCharset) { + return new Row(this, defaultCharset); } /** diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md new file mode 100644 index 00000000000..433f1cefbd3 --- /dev/null +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md @@ -0,0 +1,339 @@ +# Table + +**NOTE**: The API is experimental and subject to change. + +*Table* is a new immutable tabular data structure based on FieldVectors. A mutable version (*MutableTable*) is expected in a subsequent release. This document describes the Table API and identifies limitations in the current release. + +--- + +Like VectorSchemaRoot, *Table* is a columnar data structure backed by Arrow arrays, or more specifically, by FieldVector objects. It differs from VectorSchemaRoot mainly in that it is fully immutable and lacks support for batch operations. Anyone processing batches of tabular data in a pipeline should continue to use VectorSchemaRoot. + +## Mutation in Table and VectorSchemaRoot + +VectorSchemaRoot provides a thin wrapper on the FieldVectors that hold its data. Individual FieldVectors can be retrieved from the VectorSchemaRoot. These FieldVectors have *setters* for modifying their elements, so VectorSchemaRoot is immutable only by convention. The protocol for mutating a vector is documented in the ValueVector class: + +- values need to be written in order (e.g. index 0, 1, 2, 5) +- null vectors start with all values as null before writing anything +- for variable width types, the offset vector should be all zeros before writing +- you must call setValueCount before a vector can be read +- you should never write to a vector once it has been read. + +The rules aren't enforced by the API so the programmer is responsible for ensuring that they are followed. Failure to do so could lead to runtime exceptions. + +_Table_, on the other hand, is actually immutable. The underlying vectors are not exposed. When a Table is created from existing vectors, their memory is transferred to new vectors, so subsequent changes to the original vectors can't impact the new table's values. + +## What's in a Table? + +Like VectorSchemaRoot, Table consists of a `Schema` and an ordered collection of `FieldVector` objects, but it is designed to be accessed via a row-oriented interface. + +## Table API: Creating Tables + +### Creating a Table from a VectorSchemaRoot + +Tables are created from a VectorSchemaRoot as shown below. The memory buffers holding the data are transferred from the VectorSchemaRoot to new vectors in the new Table, clearing the original VectorSchemaRoot in the process. This ensures that the data in your new Table is never changed. Since the buffers are transferred rather than copied, this is a very low overhead operation. + +```java +VectorSchemaRoot vsr = getMyVsr(); +Table t = new Table(vsr); +``` + +If you now update the FieldVectors used to create the VectorSchemaRoot (using some variation of `ValueVector#setSafe()`), the VectorSchemaRoot *vsr* would reflect those changes, but the values in Table *t* are unchanged. + +***Current Limitation:*** Due to an unresolved limitation in `CDataReferenceManager`, you cannot currently create a Table from a VectorSchemaRoot that was created in native code and transferred to Java via the C-Data Interface. + +### Creating a Table from ValueVectors + +Tables can be created from ValueVectors as shown below. + +```java +IntVector myVector = createMyIntVector(); +VectorSchemaRoot vsr1 = new VectorSchemaRoot(myVector); +``` + +or + +```java +IntVector myVector = createMyIntVector(); +List fvList = List.of(myVector); +VectorSchemaRoot vsr1 = new VectorSchemaRoot(fvList); +``` + +It is rarely a good idea to share vectors between multiple VectorSchemaRoots, and it would not be a good idea to share them between VectorSchemaRoots and tables. Creating a VectorSchemaRoot from a list of vectors does not cause the reference counts for the vectors to be incremented. Unless you manage the counts manually, the code shown below would lead to more references to the vectors than reference counts, and that could lead to trouble. There is an implicit assumption that the vectors were created for use by *one* VectorSchemaRoot that this code violates. + +*Don't do this:* + +```Java +IntVector myVector = createMyIntVector(); // Reference count for myVector = 1 +VectorSchemaRoot vsr1 = new VectorSchemaRoot(myVector); // Still one reference +VectorSchemaRoot vsr2 = new VectorSchemaRoot(myVector); +// Ref count is still one, but there are two VSRs with a reference to myVector +vsr2.clear(); // Reference count for myVector is 0. +``` + +What is happening is that the reference counter works at a lower level than the VectorSchemaRoot interface. A reference counter counts references to ArrowBuf instances that control memory buffers. It doesn't count references to the ValueVectors that hold *them*. In the example above, each ArrowBuf is held by one ValueVector, so there is only one reference. This distinction is blurred though, when you call the VectorSchemaRoot's clear() method, which frees the memory held by each of the vectors it references even though another instance might refer to the same vectors. + +When you create Tables from vectors, it's assumed that there are no external references to those vectors. But, just to be on the safe side, the buffers underlying these vectors are transferred to new ValueVectors in the new Table, and the original vectors are cleared. + +*Don't do this either, but note the difference from above:* + +```Java +IntVector myVector = createMyIntVector(); // Reference count for myVector = 1 +Table t1 = new Table(myVector); // myVector is cleared; Table t1 has a new hidden vector with + // the data from myVector +Table t2 = new Table(myVector); // t2 has no rows because the myVector was just cleared + // t1 continues to have the data from the original vector +t2.clear(); // no change because t2 is already empty and t1 is independent +``` + +With Tables, memory is explicitly transferred on instantiatlon so the buffers are held by that table are held by *only* that table. + +#### Creating Tables with dictionary-encoded vectors + +***Note: this section is highly speculative*** + +Another point of difference is that dictionary-encoding is managed separately from VectorSchemaRoot, while Tables hold an optional DictionaryProvider instance. If any vectors in the source data are encoded, a DictionaryProvider must be set to un-encode the values. + +```java +VectorSchemaRoot vsr = myVsr(); +DictionaryProvider provider = myProvider(); +Table t = new Table(vsr, provider); +``` + +In the immutable Table case, dictionaries are used in a way that's similar to the approach used with ValueVectors. To decode a vector, the user provides the dictionary id and the name of the vector to decode: + +```Java +Table t = new Table(vsr, provider); +ValueVector decodedName = t.decode("name", 1L); +``` + +To encode a vector from a table, a similar approach is used: + +```Java +Table t = new Table(vsr, provider); +ValueVector encodedName = t.encode("name", 1L); +``` + +***Current Limitation:*** One difference is the method that produces TSV formatted output has an extra switch instructing the Table to replace the encoded output with the decoded output where possible: + +```java +String output = myTable.contentToTSVString(true); +``` + +### Freeing memory explicitly + +Tables use off-heap memory that must be freed when it is no longer needed. Table implements AutoCloseable so the best way to create one is in a try-with-resources block: + +```java +try (VectorSchemaRoot vsr = myMethodForGettingVsrs(); + Table t = new Table(vsr)) { + // do useful things. +} +``` + +If you don't use a try-with-resources block, you must close the Table manually: + +````java +try { + VectorSchemaRoot vsr = myMethodForGettingVsrs(); + Table t = new Table(vsr); + // do useful things. +} finally { + vsr.close(); + t.close(); +} +```` + +Manually closing should be performed in a finally block. + +## Table API: getting the schema + +You get the table's schema the same way you do with a VectorSchemaRoot: + +```java +Schema s = table.getSchema(); +``` + +## Table API: Adding and removing vectors + +Table provides facilities for adding and removing FieldVectors modeled on the same functionality in VectorSchemaRoot. As with VectorSchemaRoot, these operations return new instances rather than modifiying the original instance in-place. + +```java +try (Table t = new Table(vectorList)) { + IntVector v3 = new IntVector("3", intFieldType, allocator); + Table t2 = t.addVector(2, v3); + Table t3 = t2.removeVector(1); + // don't forget to close t2 and t3 +} +``` + +## Table API: Slicing tables + +Table supports *slice()* operations, where a slice of a source table is a second Table that refers to a single, contiguous range of rows in the source. + +```Java +try (Table t = new Table(vectorList)) { + Table t2 = t.slice(100, 200); // creates a slice referencing the values in range (100, 200] + ... +} +``` + +If you created a slice with *all* the values in the source table (as shown below), how would that differ from a new Table constructed with the same vectors as the source? + +```Java +try (Table t = new Table(vectorList)) { + Table t2 = t.slice(0, t.getRowCount()); // creates a slice referencing all the values in t + // ... +} +``` + +The difference is that when you *construct* a new table, the buffers are transferred from the source vectors to new vectors in the destination. With a slice, both tables share the same underlying vectors. That's OK, though, since both Tables are immutable. + +Slices will not be supported in MutableTables. + +## Table API: Row operations + +Row-based access is supported using a Row object. Row provides *get()* methods by both vector name and vector position, but no *set()* operations. It is important to recognize that it's NOT a reified row, but rather operates like a cursor where the data from numerous logical rows in the Table can be viewed (one row at a time) using the same Row instance. See "Getting around" below for information about how to navigate through the table. + +**Note**: A mutable row implementation is expected with the release of MutableTable, which will support both mutable and immutable Rows. + +### Getting a row + +Calling `immutableRow()` on any table instance returns a row supporting read operations. + +```java +Row r = table.immutableRow(); +``` + +### Getting around + +Since rows are iterable, you can traverse a table using a standard while loop: + +```java +Row r = table.immutableRow(); +while (c.hasNext()) { + c.next(); + // do something useful here +} +``` + +Table implements `Iterable` so you can access rows directly from Table in an enhanced *for* loop: + +```java +for (Row row: table) { + int age = row.getInt("age"); + boolean nameIsNull = row.isNull("name"); + ... +} +``` + +Finally, while rows are usually iterated in the order of the underlying data vectors, but they are also positionable using the `Row#setPosition()` method, so you can skip to a specific row. Row numbers are 0-based. + +```java +Row r = table.immutableRow(); +int age101 = c.setPosition(101); // change position directly to 101 +``` + +Any changes to position are of course applied to all the columns in the table. + +Note that you must call `next()`, or `setPosition()` before accessing values via a row. Failure to do so results in a runtime exception. + +### Read operations using rows + +Methods are available for getting values by vector name and vector index, where index is the 0-based position of the vector in the table. For example, assuming 'age' is the 13th vector in 'table', the following two gets are equivalent: + +```java +Row r = table.immutableRow(); +c.next(); // position the row at the first value +int age1 = c.get("age"); // gets the value of vector named 'age' in the table at row 0 +int age2 = c.get(12); // gets the value of the 13th vecto in the table at row 0 +``` + +You can also get value using a NullableHolder. For example: + +```Java +NullableIntHolder holder = new NullableIntHolder(); +int b = row.getInt("age", holder); +``` + +This can be used to retrieve values without creating a new Object for each. + +In addition to getting values, you can check if a value is null using `isNull()` and you can get the current row number: + +```java +boolean name0isNull = row.isNull("name"); +int row = row.getRowNumber(); +``` + +Note that while there are getters for most vector types (e.g. *getInt()* for use with IntVector) and a generic *isNull()* method, there is no *getNull()* method for use with the NullVector type or *getZero()* for use with ZeroVector (a zero-length vector of any type). + +#### Reading values as Objects + +For any given vector type, the basic *get()* method returns a primitive value wherever possible. For example, *getTimeStampMicro()* returns a long value that encodes the timestamp. To get the LocalDateTime object representing that timestamp in Java, another method with 'Obj' appended to the name is provided. For example: + +```java +long ts = row.getTimeStampMicro(); +LocalDateTime tsObject = row.getTimeStampMicroObj(); +``` + +The exception to this naming scheme is for complex vector types (List, Map, Schema, Union, DenseUnion, and ExtensionType). These always return objects rather than primitives so no "Obj" extension is required. It is expected that some users may subclass Row to add getters that are more specific to their needs. + +#### Reading VarChars and LargeVarChars + +Strings in arrow are represented as byte arrays, encoded with a particular Charset object. There are two ways to handle Charset in the getters. One uses the default Charset; the other takes a charset as an argument to the getter: + +```Java +String v1 = row.get("first_name"); // uses the default encoding for the table + +String v2 = row.get("first_name", StandardCharsets.US_ASCII); // specifies the encoding +``` + +What the default coding *is* will depend on how the Row was constructed. If you use: + +```Java +Row r = table.immutableRow(); +``` + +Then the default encoding is set as StandardCharsets.UTF_8. However, you can also provide a default charset when you create the row. + +```java +Row r = table.immutableRow(StandardCharsets.US_ASCII); +``` + +Now US_ASCII will be used whenever you get a String value without specifying a Charset in the getter. + +## Table API: Converting a Table to a VectorSchemaRoot + +Tables can be converted to VectorSchemaRoot objects using the *toVectorSchemaRoot()* method. + +```java +VectorSchemaRoot root = myTable.toVectorSchemaRoot(); +``` + +Buffers are transferred to the VectorSchemaRoot and the Table is cleared. + +## Table API: Working with the Streaming API and the C-Data interface + +The ability to work with native code is required for many Arrow features. This section describes how tables can be be exported and imported using two mechanisms: the C-Data Interface and the Streaming API. + +In both cases, the current solution works by converting the data to a VectorSchemaRoot and using the existing facilities for transferring the data. This is not ideal because conversion to a VectorSchemaRoot breaks the immutability guarantees, arguably when they're most desirable. + +### Using the Streaming API with Tables + +***Current limitation: Streaming API is not currently supported.*** + +Ideally, it would be possible to load a construct a table directly from an ArrowStreamReader, but this is not currently supported. + +### Using the C-Data interface with Tables + +***Current limitation: Data transferred from native code using the C-Data-interface cannot be used in a table, because the current implementation of CDataReferenceManager does not support the transfer operation.*** + +Data can be transferred from a Table to native code by using methods defined in the `org.apache.arrow.c.Data` class. + +```java + + +``` + +## Implementation notes + +The current version does not support ChunkedArrays or any form of row-group. Support for ChunkedArrows or row groups will be considered for a future release. \ No newline at end of file diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/Cursor.java b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java similarity index 97% rename from java/vector/src/main/java/org/apache/arrow/vector/table/Cursor.java rename to java/vector/src/main/java/org/apache/arrow/vector/table/Row.java index 98b4afa4885..d7c2b31e6f3 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/Cursor.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java @@ -95,41 +95,41 @@ import org.apache.arrow.vector.holders.NullableUInt8Holder; /** - * Cursor is a positionable, immutable cursor backed by a {@link Table}. If a row in a table is + * Row is a positionable, immutable cursor backed by a {@link Table}. If a row in a table is * marked as deleted, it is skipped when iterating. * *

Getters are provided for most vector types. The exceptions being {@link org.apache.arrow.vector.NullVector}, * which only contains null values and has no getter, and {@link org.apache.arrow.vector.ZeroVector}, * which is a zero-length vector of any type */ -public class Cursor extends BaseCursor implements Iterator { +public class Row extends BaseRow implements Iterator { /** Indicates whether the next non-deleted row has been determined yet. */ private boolean nextRowSet; /** * An iterator that returns every row in the table, deleted or not. The implemented next() and - * hasNext() methods in Cursor wrap it with a filter to get only the non-deleted ones. + * hasNext() methods in Row wrap it with a filter to get only the non-deleted ones. */ private final Iterator iterator = intIterator(); /** - * Constructs a new BaseCursor backed by the given table. + * Constructs a new BaseRow backed by the given table. * - * @param table the table that this Cursor object represents + * @param table the table that this Row object represents */ - public Cursor(BaseTable table) { + public Row(BaseTable table) { super(table); } /** * Constructs a newCursor backed by the given table. * - * @param table the table that this Cursor object represents + * @param table the table that this Row object represents * @param charset the standard charset for decoding bytes into strings. Note: This can be * overridden for individual columns */ - public Cursor(BaseTable table, Charset charset) { + public Row(BaseTable table, Charset charset) { super(table, charset); } @@ -137,16 +137,16 @@ public Cursor(BaseTable table, Charset charset) { * Resets the current row to -1 and returns this object. */ @Override - Cursor resetPosition() { - return (Cursor) super.resetPosition(); + Row resetPosition() { + return (Row) super.resetPosition(); } /** - * Moves this Cursor to the given 0-based row index. + * Moves this Row to the given 0-based row index. * - * @return this Cursor for chaining + * @return this Row for chaining */ - public Cursor setPosition(int rowNumber) { + public Row setPosition(int rowNumber) { this.rowNumber = rowNumber; this.nextRowSet = false; return this; @@ -171,7 +171,7 @@ public boolean isNull(int columnIndex) { /** * Returns an object representing the value in the named ExtensionTypeVector at the currentRow. An - * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalStateException is thrown if the column is not present in the Row and an * IllegalArgumentException is thrown if the type is incorrect. */ public Object getExtensionType(int vectorIndex) { @@ -181,7 +181,7 @@ public Object getExtensionType(int vectorIndex) { /** * Returns an object representing the value in the ExtensionTypeVector at the currentRow. An - * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalStateException is thrown if the column is not present in the Row and an * IllegalArgumentException is thrown if it has a different type. * * @param columnName The name of the vector providing the result @@ -194,7 +194,7 @@ public Object getExtensionType(String columnName) { /** * Returns a Map from the column of the given name at the current row. An IllegalStateException is - * thrown if the column is not present in the Cursor and an IllegalArgumentException is thrown if + * thrown if the column is not present in the Row and an IllegalArgumentException is thrown if * it has a different type. */ public List getMap(int vectorIndex) { @@ -204,7 +204,7 @@ public List getMap(int vectorIndex) { /** * Returns a Map from the column of the given name at the current row. An IllegalStateException is - * thrown if the column is not present in the Cursor and an IllegalArgumentException is thrown if + * thrown if the column is not present in the Row and an IllegalArgumentException is thrown if * it has a different type */ public List getMap(String columnName) { @@ -214,7 +214,7 @@ public List getMap(String columnName) { /** * Returns an Object from the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalStateException is thrown if the column is not present in the Row and an * IllegalArgumentException is thrown if it has a different type */ public Object getStruct(int vectorIndex) { @@ -224,7 +224,7 @@ public Object getStruct(int vectorIndex) { /** * Returns an Object from the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalStateException is thrown if the column is not present in the Row and an * IllegalArgumentException is thrown if it has a different type */ public Object getStruct(String columnName) { @@ -234,7 +234,7 @@ public Object getStruct(String columnName) { /** * Returns a List from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalStateException is thrown if the column is not present in the Row and an * IllegalArgumentException is thrown if it has a different type */ public Object getUnion(int vectorIndex) { @@ -244,7 +244,7 @@ public Object getUnion(int vectorIndex) { /** * Returns an object from the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalStateException is thrown if the column is not present in the Row and an * IllegalArgumentException is thrown if it has a different type */ public Object getUnion(String columnName) { @@ -254,7 +254,7 @@ public Object getUnion(String columnName) { /** * Returns an object from the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalStateException is thrown if the column is not present in the Row and an * IllegalArgumentException is thrown if it has a different type */ public Object getDenseUnion(String columnName) { @@ -264,7 +264,7 @@ public Object getDenseUnion(String columnName) { /** * Returns a List from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalStateException is thrown if the column is not present in the Row and an * IllegalArgumentException is thrown if it has a different type */ public Object getDenseUnion(int vectorIndex) { @@ -274,7 +274,7 @@ public Object getDenseUnion(int vectorIndex) { /** * Returns a List from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present in the Cursor and an IllegalArgumentException is thrown + * is thrown if the column is not present in the Row and an IllegalArgumentException is thrown * if it has a different type */ public List getList(String columnName) { @@ -294,7 +294,7 @@ public List getList(int columnIndex) { /** * Returns an int from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present in the Cursor and an IllegalArgumentException is thrown + * is thrown if the column is not present in the Row and an IllegalArgumentException is thrown * if it has a different type */ public int getInt(String columnName) { @@ -314,7 +314,7 @@ public int getInt(int columnIndex) { /** * Updates the holder with the value at the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalStateException is thrown if the column is not present in the Row and an * IllegalArgumentException is thrown if it has a different type */ public void getInt(String columnName, NullableIntHolder holder) { @@ -334,7 +334,7 @@ public void getInt(int columnIndex, NullableIntHolder holder) { /** * Returns an int from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present in the Cursor and an IllegalArgumentException is thrown + * is thrown if the column is not present in the Row and an IllegalArgumentException is thrown * if it has a different type */ public int getUInt4(String columnName) { @@ -354,7 +354,7 @@ public int getUInt4(int columnIndex) { /** * Updates the holder with the value at the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalStateException is thrown if the column is not present in the Row and an * IllegalArgumentException is thrown if it has a different type */ public void getUInt4(String columnName, NullableUInt4Holder holder) { @@ -1635,7 +1635,7 @@ public byte[] getLargeVarBinary(int columnIndex) { /** * Returns a String from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present in the Cursor and an IllegalArgumentException is thrown + * is thrown if the column is not present in the Row and an IllegalArgumentException is thrown * if it has a different type * *

StandardCharsets.UTF_8 is used as the charset @@ -1647,7 +1647,7 @@ public String getVarChar(String columnName) { /** * Returns a String from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present in the Cursor and an IllegalArgumentException is thrown + * is thrown if the column is not present in the Row and an IllegalArgumentException is thrown * if it has a different type * * @param vectorName the name of the FieldVector holding the value @@ -1660,7 +1660,7 @@ public String getVarChar(String vectorName, Charset charset) { /** * Returns a String from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalStateException is thrown if the column is not present in the Row and an * IllegalArgumentException is thrown if it has a different type * * @param columnIndex the index of the FieldVector holding the value @@ -1672,7 +1672,7 @@ public String getVarChar(int columnIndex) { /** * Returns a String from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalStateException is thrown if the column is not present in the Row and an * IllegalArgumentException is thrown if it has a different type * * @param columnIndex the index of the FieldVector holding the value @@ -1685,7 +1685,7 @@ public String getVarChar(int columnIndex, Charset charset) { /** * Returns a String from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present in the Cursor and an IllegalArgumentException is thrown + * is thrown if the column is not present in the Row and an IllegalArgumentException is thrown * if it has a different type * *

StandardCharsets.UTF_8 is used as the charset, unless this cursor was created with a default @@ -1698,7 +1698,7 @@ public String getLargeVarChar(String columnName) { /** * Returns a String from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present in the Cursor and an IllegalArgumentException is thrown + * is thrown if the column is not present in the Row and an IllegalArgumentException is thrown * if it has a different type * * @param vectorName the name of the FieldVector holding the value @@ -1711,7 +1711,7 @@ public String getLargeVarChar(String vectorName, Charset charset) { /** * Returns a String from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalStateException is thrown if the column is not present in the Row and an * IllegalArgumentException is thrown if it has a different type */ public String getLargeVarChar(int columnIndex) { @@ -1721,7 +1721,7 @@ public String getLargeVarChar(int columnIndex) { /** * Returns a String from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present in the Cursor and an + * IllegalStateException is thrown if the column is not present in the Row and an * IllegalArgumentException is thrown if it has a different type * * @param columnIndex the index of the FieldVector holding the value @@ -1753,7 +1753,7 @@ public boolean hasNext() { * @throws NoSuchElementException if there are no more rows */ @Override - public Cursor next() { + public Row next() { if (!nextRowSet && !setNextObject()) { throw new NoSuchElementException(); } diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/Table.java b/java/vector/src/main/java/org/apache/arrow/vector/table/Table.java index 5c2f2425e40..a5f142681c7 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/Table.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/Table.java @@ -34,7 +34,7 @@ * *

See {@link VectorSchemaRoot} for batch processing use cases */ -public class Table extends BaseTable implements Iterable { +public class Table extends BaseTable implements Iterable { /** Constructs new instance containing each of the given vectors. */ public Table(Iterable vectors) { @@ -164,16 +164,16 @@ public Table slice(int index, int length) { return new Table(sliceVectors); } - /** Returns a Cursor iterator for this Table. */ + /** Returns a Row iterator for this Table. */ @Override - public Iterator iterator() { + public Iterator iterator() { - return new Iterator() { + return new Iterator() { - private final Cursor row = new Cursor(Table.this); + private final Row row = new Row(Table.this); @Override - public Cursor next() { + public Row next() { row.next(); return row; } diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/package-info.java b/java/vector/src/main/java/org/apache/arrow/vector/table/package-info.java new file mode 100644 index 00000000000..7133183a28a --- /dev/null +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/package-info.java @@ -0,0 +1,25 @@ +/* + * 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.table; + +/** + * Support for Table, an immutable, columnar, tabular data structure based on FieldVectors. + * + * See the README.md file in this directory for detailed information about Table class and supporting classes. + * + */ diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java index fddd056e884..efa33fce792 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java @@ -197,7 +197,7 @@ void contentToTsvString() { try (Table t = Table.of(v)) { assertEquals(3, t.rowCount); List values = new ArrayList<>(); - for (Cursor r : t) { + for (Row r : t) { values.add(r.getInt(INT_VECTOR_NAME)); } assertEquals(3, values.size()); diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/CursorTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java similarity index 94% rename from java/vector/src/test/java/org/apache/arrow/vector/table/CursorTest.java rename to java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index 0506ef0d710..5079075b2b2 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/CursorTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -52,7 +52,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -class CursorTest { +class RowTest { private BufferAllocator allocator; @@ -70,7 +70,7 @@ public void terminate() { void constructor() { List vectorList = twoIntColumns(allocator); try (Table t = new Table(vectorList)) { - Cursor c = t.immutableCursor(StandardCharsets.US_ASCII); + Row c = t.immutableCursor(StandardCharsets.US_ASCII); assertEquals(StandardCharsets.US_ASCII, c.getDefaultCharacterSet()); } } @@ -79,7 +79,7 @@ void constructor() { void at() { List vectorList = twoIntColumns(allocator); try (Table t = new Table(vectorList)) { - Cursor c = t.immutableCursor(); + Row c = t.immutableCursor(); assertEquals(c.getRowNumber(), -1); c.setPosition(1); assertEquals(c.getRowNumber(), 1); @@ -90,7 +90,7 @@ void at() { void getIntByVectorIndex() { List vectorList = twoIntColumns(allocator); try (Table t = new Table(vectorList)) { - Cursor c = t.immutableCursor(); + Row c = t.immutableCursor(); c.setPosition(1); assertEquals(2, c.getInt(0)); } @@ -100,7 +100,7 @@ void getIntByVectorIndex() { void getIntByVectorName() { List vectorList = twoIntColumns(allocator); try (Table t = new Table(vectorList)) { - Cursor c = t.immutableCursor(); + Row c = t.immutableCursor(); c.setPosition(1); assertEquals(2, c.getInt(INT_VECTOR_NAME_1)); } @@ -110,7 +110,7 @@ void getIntByVectorName() { void hasNext() { List vectorList = twoIntColumns(allocator); try (Table t = new Table(vectorList)) { - Cursor c = t.immutableCursor(); + Row c = t.immutableCursor(); assertTrue(c.hasNext()); c.setPosition(1); assertFalse(c.hasNext()); @@ -121,7 +121,7 @@ void hasNext() { void next() { List vectorList = twoIntColumns(allocator); try (Table t = new Table(vectorList)) { - Cursor c = t.immutableCursor(); + Row c = t.immutableCursor(); c.setPosition(0); c.next(); assertEquals(1, c.getRowNumber()); @@ -132,7 +132,7 @@ void next() { void isNull() { List vectorList = twoIntColumns(allocator); try (Table t = new Table(vectorList)) { - Cursor c = t.immutableCursor(); + Row c = t.immutableCursor(); c.setPosition(1); assertFalse(c.isNull(0)); } @@ -142,7 +142,7 @@ void isNull() { void isNullByFieldName() { List vectorList = twoIntColumns(allocator); try (Table t = new Table(vectorList)) { - Cursor c = t.immutableCursor(); + Row c = t.immutableCursor(); c.setPosition(1); assertFalse(c.isNull(INT_VECTOR_NAME_1)); } @@ -152,7 +152,7 @@ void isNullByFieldName() { void fixedWidthVectorTest() { List vectorList = fixedWidthVectors(allocator, 2); try (Table t = new Table(vectorList)) { - Cursor c = t.immutableCursor(); + Row c = t.immutableCursor(); c.setPosition(1); assertFalse(c.isNull("bigInt_vector")); assertEquals(c.getInt("int_vector"), c.getInt(0)); @@ -186,7 +186,7 @@ void testSimpleListVector1() { try (ListVector listVector = simpleListVector(allocator); VectorSchemaRoot vectorSchemaRoot = VectorSchemaRoot.of(listVector); Table table = new Table(vectorSchemaRoot)) { - for (Cursor c : table) { + for (Row c : table) { @SuppressWarnings("unchecked") List list = (List) c.getList(INT_LIST_VECTOR_NAME); assertEquals(10, list.size()); @@ -199,7 +199,7 @@ void testSimpleListVector2() { try (ListVector listVector = simpleListVector(allocator); VectorSchemaRoot vectorSchemaRoot = VectorSchemaRoot.of(listVector); Table table = new Table(vectorSchemaRoot)) { - for (Cursor c : table) { + for (Row c : table) { @SuppressWarnings("unchecked") List list = (List) c.getList(0); assertEquals(10, list.size()); @@ -213,7 +213,7 @@ void testSimpleStructVector1() { VectorSchemaRoot vectorSchemaRoot = VectorSchemaRoot.of(structVector); Table table = new Table(vectorSchemaRoot)) { System.out.println(table.contentToTSVString()); - for (Cursor c : table) { + for (Row c : table) { @SuppressWarnings("unchecked") JsonStringHashMap struct = (JsonStringHashMap) c.getStruct(STRUCT_VECTOR_NAME); @@ -231,7 +231,7 @@ void testSimpleUnionVector() { try (UnionVector unionVector = simpleUnionVector(allocator); VectorSchemaRoot vsr = VectorSchemaRoot.of(unionVector); Table table = new Table(vsr)) { - Cursor c = table.immutableCursor(); + Row c = table.immutableCursor(); c.setPosition(0); Object object0 = c.getUnion(UNION_VECTOR_NAME); c.setPosition(1); @@ -248,7 +248,7 @@ void testSimpleDenseUnionVector() { try (DenseUnionVector unionVector = simpleDenseUnionVector(allocator); VectorSchemaRoot vsr = VectorSchemaRoot.of(unionVector); Table table = new Table(vsr)) { - Cursor c = table.immutableCursor(); + Row c = table.immutableCursor(); c.setPosition(0); Object object0 = c.getDenseUnion(UNION_VECTOR_NAME); c.setPosition(1); @@ -266,7 +266,7 @@ void testSimpleMapVector1() { Table table = Table.of(mapVector)) { int i = 1; - for (Cursor c : table) { + for (Row c : table) { @SuppressWarnings("unchecked") List> list = (List>) c.getMap(BIGINT_INT_MAP_VECTOR_NAME); diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/TableTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/TableTest.java index 13ed1e59b4a..2c0dbcfbcd3 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/TableTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/TableTest.java @@ -54,7 +54,7 @@ public void init() { void of() { List vectorList = twoIntColumns(allocator); try (Table t = Table.of(vectorList.toArray(new FieldVector[2]))) { - Cursor c = t.immutableCursor(); + Row c = t.immutableCursor(); assertEquals(2, t.getRowCount()); assertEquals(2, t.getVectorCount()); IntVector intVector1 = (IntVector) vectorList.get(0); @@ -80,7 +80,7 @@ void constructor() { try (Table t = new Table(vectorList, 2)) { assertEquals(2, t.getRowCount()); assertEquals(2, t.getVectorCount()); - Cursor c = t.immutableCursor(); + Row c = t.immutableCursor(); IntVector intVector1 = (IntVector) vectorList.get(0); c.setPosition(0); @@ -131,11 +131,11 @@ void removeVector() { void iterator1() { List vectorList = twoIntColumns(allocator); try (Table t = new Table(vectorList)) { - Iterator iterator = t.iterator(); + Iterator iterator = t.iterator(); assertNotNull(iterator); assertTrue(iterator.hasNext()); int sum = 0; - for (Cursor row : t) { + for (Row row : t) { sum += row.getInt(0); } assertEquals(3, sum); @@ -148,13 +148,13 @@ void iterator1() { void iterator2() { List vectorList = twoIntColumns(allocator); try (Table t = new Table(vectorList)) { - Iterator iterator = t.iterator(); + Iterator iterator = t.iterator(); assertNotNull(iterator); assertTrue(iterator.hasNext()); int sum = 0; - Iterator it = t.iterator(); + Iterator it = t.iterator(); while (it.hasNext()) { - Cursor row = it.next(); + Row row = it.next(); sum += row.getInt(0); } assertEquals(3, sum); @@ -198,7 +198,7 @@ void constructFromVsr() { List vectorList = twoIntColumns(allocator); try (VectorSchemaRoot vsr = new VectorSchemaRoot(vectorList)) { Table t = new Table(vsr); - Cursor c = t.immutableCursor(); + Row c = t.immutableCursor(); assertEquals(2, t.rowCount); assertEquals(0, vsr.getRowCount()); // memory is copied for slice, not transferred IntVector intVector1 = (IntVector) vectorList.get(0); diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java b/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java index 875e97c61fc..a8acd180ddd 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java @@ -58,7 +58,6 @@ import org.apache.arrow.vector.types.Types; import org.apache.arrow.vector.types.pojo.Field; import org.apache.arrow.vector.types.pojo.FieldType; -import org.junit.platform.commons.util.Preconditions; public class TestUtils { @@ -77,7 +76,6 @@ public class TestUtils { */ static List twoIntColumns(BufferAllocator allocator) { List vectorList = new ArrayList<>(); - Preconditions.condition(allocator != null, "allocator is null"); IntVector v1 = new IntVector(INT_VECTOR_NAME_1, allocator); v1.allocateNew(2); v1.set(0, 1); @@ -99,7 +97,6 @@ static List twoIntColumns(BufferAllocator allocator) { */ static List intPlusVarcharColumns(BufferAllocator allocator) { List vectorList = new ArrayList<>(); - Preconditions.condition(allocator != null, "allocator is null"); IntVector v1 = new IntVector(INT_VECTOR_NAME_1, allocator); v1.allocateNew(2); v1.set(0, 1); From abdc234576b682564a65f33a1f38f49133c5a04f Mon Sep 17 00:00:00 2001 From: Larry White Date: Thu, 29 Sep 2022 14:19:17 -0400 Subject: [PATCH 03/40] Update readme with description of exports --- .../org/apache/arrow/vector/table/README.md | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md index 433f1cefbd3..955cec94b08 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md @@ -313,26 +313,25 @@ Buffers are transferred to the VectorSchemaRoot and the Table is cleared. ## Table API: Working with the Streaming API and the C-Data interface -The ability to work with native code is required for many Arrow features. This section describes how tables can be be exported and imported using two mechanisms: the C-Data Interface and the Streaming API. +The ability to work with native code is required for many Arrow features. This section describes how tables can be be exported and imported. -In both cases, the current solution works by converting the data to a VectorSchemaRoot and using the existing facilities for transferring the data. This is not ideal because conversion to a VectorSchemaRoot breaks the immutability guarantees, arguably when they're most desirable. +### Exporting Tables to native code using the C-Data interface -### Using the Streaming API with Tables +This works by converting the data to a VectorSchemaRoot and using the existing facilities for transferring the data. This would not generally be ideal because conversion to a VectorSchemaRoot breaks the immutability guarantees. Using the static utility methods defined in the class org.apache.arrow.c.Data` avoids this concern because the vector schema root used is not expored. See the example code below: -***Current limitation: Streaming API is not currently supported.*** - -Ideally, it would be possible to load a construct a table directly from an ArrowStreamReader, but this is not currently supported. +```java +Data.exportTable(bufferAllocator, table, dictionaryProvider, outArrowArray); +``` -### Using the C-Data interface with Tables +***Current limitation: Data imported from native code using the C-Data-interface cannot be used in a table, because the current implementation of CDataReferenceManager does not support the transfer operation.*** -***Current limitation: Data transferred from native code using the C-Data-interface cannot be used in a table, because the current implementation of CDataReferenceManager does not support the transfer operation.*** +### Exporting Tables to native code using the Streaming API -Data can be transferred from a Table to native code by using methods defined in the `org.apache.arrow.c.Data` class. +***Current limitation: Streaming API is not currently supported.*** -```java -``` +***Current limitation: Data imported from native code using the Streaming API cannot be used in a table, because the current implementation of CDataReferenceManager does not support the transfer operation.*** ## Implementation notes From 0062d41d5a4058d59b014c577a06f669cd0ddd20 Mon Sep 17 00:00:00 2001 From: Larry White Date: Thu, 29 Sep 2022 14:44:04 -0400 Subject: [PATCH 04/40] Added "experimental API" text to class javadoc --- .../main/java/org/apache/arrow/vector/table/BaseRow.java | 3 +++ .../main/java/org/apache/arrow/vector/table/BaseTable.java | 6 +++++- .../src/main/java/org/apache/arrow/vector/table/Row.java | 3 +++ .../src/main/java/org/apache/arrow/vector/table/Table.java | 3 +++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/BaseRow.java b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseRow.java index ffaab56e6b3..c018798a53b 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/BaseRow.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseRow.java @@ -22,6 +22,9 @@ /** * Provides row based access to the data held by a {@link Table}. + * + *

+ * This API is EXPERIMENTAL. */ public abstract class BaseRow { diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java index c0a046da382..e83a311adc9 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java @@ -37,7 +37,11 @@ import org.apache.arrow.vector.types.pojo.Schema; import org.apache.arrow.vector.util.TransferPair; -/** Abstract base class for Table with mutable and immutable concrete implementations. */ +/** + * Abstract base class for Table. + *

+ * This API is EXPERIMENTAL. + */ public abstract class BaseTable implements AutoCloseable { /** The field vectors holding the data in this table. */ diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java index d7c2b31e6f3..cb2d20f86e5 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java @@ -101,6 +101,9 @@ *

Getters are provided for most vector types. The exceptions being {@link org.apache.arrow.vector.NullVector}, * which only contains null values and has no getter, and {@link org.apache.arrow.vector.ZeroVector}, * which is a zero-length vector of any type + * + *

+ * This API is EXPERIMENTAL. */ public class Row extends BaseRow implements Iterator { diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/Table.java b/java/vector/src/main/java/org/apache/arrow/vector/table/Table.java index a5f142681c7..49ed8d6f243 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/Table.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/Table.java @@ -33,6 +33,9 @@ * Table is an immutable tabular data structure. * *

See {@link VectorSchemaRoot} for batch processing use cases + * + *

+ * This API is EXPERIMENTAL. */ public class Table extends BaseTable implements Iterable { From 8b943e10afd7612328b158d91564d417ecc1e49f Mon Sep 17 00:00:00 2001 From: Larry White Date: Fri, 30 Sep 2022 08:31:59 -0400 Subject: [PATCH 05/40] removed charset options, since arrow doesn't support anything but UTF-8 --- .../apache/arrow/vector/table/BaseRow.java | 17 +---- .../apache/arrow/vector/table/BaseTable.java | 16 +---- .../org/apache/arrow/vector/table/README.md | 46 ++++++------- .../org/apache/arrow/vector/table/Row.java | 64 ------------------- .../arrow/vector/table/BaseTableTest.java | 2 +- .../apache/arrow/vector/table/RowTest.java | 24 +++---- .../apache/arrow/vector/table/TableTest.java | 6 +- 7 files changed, 39 insertions(+), 136 deletions(-) diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/BaseRow.java b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseRow.java index c018798a53b..9d400c8f189 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/BaseRow.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseRow.java @@ -35,10 +35,9 @@ public abstract class BaseRow { protected int rowNumber = -1; /** - * Returns the standard character set to use for decoding strings. Can be overridden for - * individual columns by providing the {@link Charset} as an argument in the getter. + * Returns the standard character set to use for decoding strings. The Arrow format only supports UTF-8. */ - private Charset defaultCharacterSet = StandardCharsets.UTF_8; + private final Charset defaultCharacterSet = StandardCharsets.UTF_8; /** * Constructs a new BaseRow backed by the given table. @@ -49,18 +48,6 @@ public BaseRow(BaseTable table) { this.table = table; } - /** - * Constructs a new BaseRow backed by the given table. - * - * @param table the table that this cursor represents - * @param charset the standard charset for decoding bytes into strings. Note: This can be - * overridden for individual columns. - */ - public BaseRow(BaseTable table, Charset charset) { - this.table = table; - this.defaultCharacterSet = charset; - } - /** * Resets the row index to -1 and returns this object. */ diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java index e83a311adc9..3964fa6dad6 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java @@ -17,7 +17,6 @@ package org.apache.arrow.vector.table; -import java.nio.charset.Charset; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -270,22 +269,13 @@ FieldVector getVector(int columnIndex) { /** * Returns an immutable Row object holding a reference to this table. The default character - * encoding used by the cursor to decode Strings will be StandardCharsets.UTF_8. + * encoding used by the cursor to decode Strings will be StandardCharsets.UTF_8 as this is the only charset + * supported in Arrow format. */ - public Row immutableCursor() { + public Row immutableRow() { return new Row(this); } - /** - * Returns an immutable Row object holding a reference to this table. - * - * @param defaultCharset The default character encoding used by the cursor to decode Strings. It - * can be overridden for individual vectors in the get() method - */ - public Row immutableCursor(Charset defaultCharset) { - return new Row(this, defaultCharset); - } - /** * Returns a tab separated value of vectors (based on their java object representation). * diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md index 955cec94b08..0f822e76b0f 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md @@ -2,6 +2,8 @@ **NOTE**: The API is experimental and subject to change. +**NOTE**: Major limitations in this release are listed at the end of the document. + *Table* is a new immutable tabular data structure based on FieldVectors. A mutable version (*MutableTable*) is expected in a subsequent release. This document describes the Table API and identifies limitations in the current release. --- @@ -20,7 +22,7 @@ VectorSchemaRoot provides a thin wrapper on the FieldVectors that hold its data. The rules aren't enforced by the API so the programmer is responsible for ensuring that they are followed. Failure to do so could lead to runtime exceptions. -_Table_, on the other hand, is actually immutable. The underlying vectors are not exposed. When a Table is created from existing vectors, their memory is transferred to new vectors, so subsequent changes to the original vectors can't impact the new table's values. +_Table_, on the other hand, is immutable. The underlying vectors are not exposed. When a Table is created from existing vectors, their memory is transferred to new vectors, so subsequent changes to the original vectors can't impact the new table's values. ## What's in a Table? @@ -279,28 +281,12 @@ The exception to this naming scheme is for complex vector types (List, Map, Sche #### Reading VarChars and LargeVarChars -Strings in arrow are represented as byte arrays, encoded with a particular Charset object. There are two ways to handle Charset in the getters. One uses the default Charset; the other takes a charset as an argument to the getter: +Strings in arrow are represented as byte arrays, encoded with the UTF-8 charset as this is the only character set supported in the Arrow format. ```Java -String v1 = row.get("first_name"); // uses the default encoding for the table - -String v2 = row.get("first_name", StandardCharsets.US_ASCII); // specifies the encoding +String v1 = row.getVarChar("first_name"); // uses the default encoding (UTF-8) ``` -What the default coding *is* will depend on how the Row was constructed. If you use: - -```Java -Row r = table.immutableRow(); -``` - -Then the default encoding is set as StandardCharsets.UTF_8. However, you can also provide a default charset when you create the row. - -```java -Row r = table.immutableRow(StandardCharsets.US_ASCII); -``` - -Now US_ASCII will be used whenever you get a String value without specifying a Charset in the getter. - ## Table API: Converting a Table to a VectorSchemaRoot Tables can be converted to VectorSchemaRoot objects using the *toVectorSchemaRoot()* method. @@ -311,11 +297,11 @@ VectorSchemaRoot root = myTable.toVectorSchemaRoot(); Buffers are transferred to the VectorSchemaRoot and the Table is cleared. -## Table API: Working with the Streaming API and the C-Data interface +## Table API: Working with the C-Data interface The ability to work with native code is required for many Arrow features. This section describes how tables can be be exported and imported. -### Exporting Tables to native code using the C-Data interface +### Exporting Tables to native code This works by converting the data to a VectorSchemaRoot and using the existing facilities for transferring the data. This would not generally be ideal because conversion to a VectorSchemaRoot breaks the immutability guarantees. Using the static utility methods defined in the class org.apache.arrow.c.Data` avoids this concern because the vector schema root used is not expored. See the example code below: @@ -323,16 +309,20 @@ This works by converting the data to a VectorSchemaRoot and using the existing f Data.exportTable(bufferAllocator, table, dictionaryProvider, outArrowArray); ``` -***Current limitation: Data imported from native code using the C-Data-interface cannot be used in a table, because the current implementation of CDataReferenceManager does not support the transfer operation.*** - -### Exporting Tables to native code using the Streaming API - -***Current limitation: Streaming API is not currently supported.*** +### Importing Tables from native code +***Current limitation: Data imported from native code using the C-Data-interface cannot be used in a table, because the current implementation of CDataReferenceManager does not support the transfer operation.*** +## Table API: Working with the C-Stream interface -***Current limitation: Data imported from native code using the Streaming API cannot be used in a table, because the current implementation of CDataReferenceManager does not support the transfer operation.*** +***Current limitation: Streaming API is not currently supported. Support is planned for a future release.*** ## Implementation notes -The current version does not support ChunkedArrays or any form of row-group. Support for ChunkedArrows or row groups will be considered for a future release. \ No newline at end of file +The following are the major limitations of v. 10.0.0 release: + +1. No support ChunkedArrays or any form of row-group. Support for ChunkedArrows or row groups will be considered for a future release. +2. No support for native interface using the C-Stream API. Support for the streaming API will be delivered with or after Item 1. +3. No ability to use Tables with data imported from native code using the C-Data API. Support for ths feature is gated on PR#13248 (https://github.com/apache/arrow/pull/13248). +4. No support for creating tables directly from Java POJOs. All data held by a table must be imported via a VectorSchemaRoot. +5. No support for mutable tables. \ No newline at end of file diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java index cb2d20f86e5..2a3f1a8786d 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java @@ -18,7 +18,6 @@ package org.apache.arrow.vector.table; import java.math.BigDecimal; -import java.nio.charset.Charset; import java.time.Duration; import java.time.LocalDateTime; import java.time.Period; @@ -125,17 +124,6 @@ public Row(BaseTable table) { super(table); } - /** - * Constructs a newCursor backed by the given table. - * - * @param table the table that this Row object represents - * @param charset the standard charset for decoding bytes into strings. Note: This can be - * overridden for individual columns - */ - public Row(BaseTable table, Charset charset) { - super(table, charset); - } - /** * Resets the current row to -1 and returns this object. */ @@ -1648,19 +1636,6 @@ public String getVarChar(String columnName) { return new String(vector.get(rowNumber), getDefaultCharacterSet()); } - /** - * Returns a String from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present in the Row and an IllegalArgumentException is thrown - * if it has a different type - * - * @param vectorName the name of the FieldVector holding the value - * @param charset the charset to use for decoding the bytes - */ - public String getVarChar(String vectorName, Charset charset) { - VarCharVector vector = (VarCharVector) table.getVector(vectorName); - return new String(vector.get(rowNumber), charset); - } - /** * Returns a String from the column with the given index at the current row. An * IllegalStateException is thrown if the column is not present in the Row and an @@ -1673,19 +1648,6 @@ public String getVarChar(int columnIndex) { return new String(vector.get(rowNumber), getDefaultCharacterSet()); } - /** - * Returns a String from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present in the Row and an - * IllegalArgumentException is thrown if it has a different type - * - * @param columnIndex the index of the FieldVector holding the value - * @param charset the charset to use for decoding the bytes - */ - public String getVarChar(int columnIndex, Charset charset) { - VarCharVector vector = (VarCharVector) table.getVector(columnIndex); - return new String(vector.get(rowNumber), charset); - } - /** * Returns a String from the column of the given name at the current row. An IllegalStateException * is thrown if the column is not present in the Row and an IllegalArgumentException is thrown @@ -1699,19 +1661,6 @@ public String getLargeVarChar(String columnName) { return new String(vector.get(rowNumber), getDefaultCharacterSet()); } - /** - * Returns a String from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present in the Row and an IllegalArgumentException is thrown - * if it has a different type - * - * @param vectorName the name of the FieldVector holding the value - * @param charset the charset to use for decoding the bytes - */ - public String getLargeVarChar(String vectorName, Charset charset) { - LargeVarCharVector vector = (LargeVarCharVector) table.getVector(vectorName); - return new String(vector.get(rowNumber), charset); - } - /** * Returns a String from the column with the given index at the current row. An * IllegalStateException is thrown if the column is not present in the Row and an @@ -1722,19 +1671,6 @@ public String getLargeVarChar(int columnIndex) { return new String(vector.get(rowNumber), getDefaultCharacterSet()); } - /** - * Returns a String from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present in the Row and an - * IllegalArgumentException is thrown if it has a different type - * - * @param columnIndex the index of the FieldVector holding the value - * @param charset the charset to use for decoding the bytes - */ - public String getLargeVarChar(int columnIndex, Charset charset) { - LargeVarCharVector vector = (LargeVarCharVector) table.getVector(columnIndex); - return new String(vector.get(rowNumber), charset); - } - // TODO: Implement getters for // List & LargeList // plus (for dealing with nulls?) diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java index efa33fce792..bb07f417928 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java @@ -182,7 +182,7 @@ void testGetVector() { void immutableCursor() { List vectorList = twoIntColumns(allocator); try (Table t = new Table(vectorList)) { - assertNotNull(t.immutableCursor()); + assertNotNull(t.immutableRow()); } } diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index 5079075b2b2..439d34f2109 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -70,8 +70,8 @@ public void terminate() { void constructor() { List vectorList = twoIntColumns(allocator); try (Table t = new Table(vectorList)) { - Row c = t.immutableCursor(StandardCharsets.US_ASCII); - assertEquals(StandardCharsets.US_ASCII, c.getDefaultCharacterSet()); + Row c = t.immutableRow(); + assertEquals(StandardCharsets.UTF_8, c.getDefaultCharacterSet()); } } @@ -79,7 +79,7 @@ void constructor() { void at() { List vectorList = twoIntColumns(allocator); try (Table t = new Table(vectorList)) { - Row c = t.immutableCursor(); + Row c = t.immutableRow(); assertEquals(c.getRowNumber(), -1); c.setPosition(1); assertEquals(c.getRowNumber(), 1); @@ -90,7 +90,7 @@ void at() { void getIntByVectorIndex() { List vectorList = twoIntColumns(allocator); try (Table t = new Table(vectorList)) { - Row c = t.immutableCursor(); + Row c = t.immutableRow(); c.setPosition(1); assertEquals(2, c.getInt(0)); } @@ -100,7 +100,7 @@ void getIntByVectorIndex() { void getIntByVectorName() { List vectorList = twoIntColumns(allocator); try (Table t = new Table(vectorList)) { - Row c = t.immutableCursor(); + Row c = t.immutableRow(); c.setPosition(1); assertEquals(2, c.getInt(INT_VECTOR_NAME_1)); } @@ -110,7 +110,7 @@ void getIntByVectorName() { void hasNext() { List vectorList = twoIntColumns(allocator); try (Table t = new Table(vectorList)) { - Row c = t.immutableCursor(); + Row c = t.immutableRow(); assertTrue(c.hasNext()); c.setPosition(1); assertFalse(c.hasNext()); @@ -121,7 +121,7 @@ void hasNext() { void next() { List vectorList = twoIntColumns(allocator); try (Table t = new Table(vectorList)) { - Row c = t.immutableCursor(); + Row c = t.immutableRow(); c.setPosition(0); c.next(); assertEquals(1, c.getRowNumber()); @@ -132,7 +132,7 @@ void next() { void isNull() { List vectorList = twoIntColumns(allocator); try (Table t = new Table(vectorList)) { - Row c = t.immutableCursor(); + Row c = t.immutableRow(); c.setPosition(1); assertFalse(c.isNull(0)); } @@ -142,7 +142,7 @@ void isNull() { void isNullByFieldName() { List vectorList = twoIntColumns(allocator); try (Table t = new Table(vectorList)) { - Row c = t.immutableCursor(); + Row c = t.immutableRow(); c.setPosition(1); assertFalse(c.isNull(INT_VECTOR_NAME_1)); } @@ -152,7 +152,7 @@ void isNullByFieldName() { void fixedWidthVectorTest() { List vectorList = fixedWidthVectors(allocator, 2); try (Table t = new Table(vectorList)) { - Row c = t.immutableCursor(); + Row c = t.immutableRow(); c.setPosition(1); assertFalse(c.isNull("bigInt_vector")); assertEquals(c.getInt("int_vector"), c.getInt(0)); @@ -231,7 +231,7 @@ void testSimpleUnionVector() { try (UnionVector unionVector = simpleUnionVector(allocator); VectorSchemaRoot vsr = VectorSchemaRoot.of(unionVector); Table table = new Table(vsr)) { - Row c = table.immutableCursor(); + Row c = table.immutableRow(); c.setPosition(0); Object object0 = c.getUnion(UNION_VECTOR_NAME); c.setPosition(1); @@ -248,7 +248,7 @@ void testSimpleDenseUnionVector() { try (DenseUnionVector unionVector = simpleDenseUnionVector(allocator); VectorSchemaRoot vsr = VectorSchemaRoot.of(unionVector); Table table = new Table(vsr)) { - Row c = table.immutableCursor(); + Row c = table.immutableRow(); c.setPosition(0); Object object0 = c.getDenseUnion(UNION_VECTOR_NAME); c.setPosition(1); diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/TableTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/TableTest.java index 2c0dbcfbcd3..787762f8f56 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/TableTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/TableTest.java @@ -54,7 +54,7 @@ public void init() { void of() { List vectorList = twoIntColumns(allocator); try (Table t = Table.of(vectorList.toArray(new FieldVector[2]))) { - Row c = t.immutableCursor(); + Row c = t.immutableRow(); assertEquals(2, t.getRowCount()); assertEquals(2, t.getVectorCount()); IntVector intVector1 = (IntVector) vectorList.get(0); @@ -80,7 +80,7 @@ void constructor() { try (Table t = new Table(vectorList, 2)) { assertEquals(2, t.getRowCount()); assertEquals(2, t.getVectorCount()); - Row c = t.immutableCursor(); + Row c = t.immutableRow(); IntVector intVector1 = (IntVector) vectorList.get(0); c.setPosition(0); @@ -198,7 +198,7 @@ void constructFromVsr() { List vectorList = twoIntColumns(allocator); try (VectorSchemaRoot vsr = new VectorSchemaRoot(vectorList)) { Table t = new Table(vsr); - Row c = t.immutableCursor(); + Row c = t.immutableRow(); assertEquals(2, t.rowCount); assertEquals(0, vsr.getRowCount()); // memory is copied for slice, not transferred IntVector intVector1 = (IntVector) vectorList.get(0); From 928d672d86d7b17d4a14b3a80ca8b823b6930d20 Mon Sep 17 00:00:00 2001 From: Larry White Date: Fri, 30 Sep 2022 09:03:46 -0400 Subject: [PATCH 06/40] Update README.md --- .../src/main/java/org/apache/arrow/vector/table/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md index 0f822e76b0f..a33b987043f 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md @@ -4,7 +4,7 @@ **NOTE**: Major limitations in this release are listed at the end of the document. -*Table* is a new immutable tabular data structure based on FieldVectors. A mutable version (*MutableTable*) is expected in a subsequent release. This document describes the Table API and identifies limitations in the current release. +*Table* is a new immutable tabular data structure based on FieldVectors. A mutable version (*MutableTable*) is expected in a subsequent release. This document describes the Table API. --- From af63c9fc8ee809a28a053bf1fe07a0f8073f99f7 Mon Sep 17 00:00:00 2001 From: Larry White Date: Fri, 30 Sep 2022 12:29:00 -0400 Subject: [PATCH 07/40] Added a variation to Data.exportTable --- .../c/src/main/java/org/apache/arrow/c/Data.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/java/c/src/main/java/org/apache/arrow/c/Data.java b/java/c/src/main/java/org/apache/arrow/c/Data.java index b931959d86b..23cd48c1317 100644 --- a/java/c/src/main/java/org/apache/arrow/c/Data.java +++ b/java/c/src/main/java/org/apache/arrow/c/Data.java @@ -115,6 +115,22 @@ public static void exportVector(BufferAllocator allocator, FieldVector vector, D exporter.export(out, vector, provider); } + /** + * Export the current contents of a Java Table using the C data + * interface format. + *

+ * The table is exported as if it were a struct array. The + * resulting ArrowArray struct keeps the record batch data and buffers alive + * until its release callback is called by the consumer. + * + * @param allocator Buffer allocator for allocating C data interface fields + * @param table Table to export + * @param out C struct where to export the record batch + */ + public static void exportTable(BufferAllocator allocator, Table table, ArrowArray out) { + exportTable(allocator, table, table.getDictionaryProvider(), out, null); + } + /** * Export the current contents of a Java Table using the C data * interface format. From 84374015df8bc1c67c796d7ce3266eb855f117fe Mon Sep 17 00:00:00 2001 From: Larry White Date: Fri, 30 Sep 2022 12:29:23 -0400 Subject: [PATCH 08/40] More tests; better documentation --- .../org/apache/arrow/vector/table/README.md | 14 +++++++ .../arrow/vector/table/BaseTableTest.java | 37 +++++++++++++++++++ .../apache/arrow/vector/table/RowTest.java | 14 ++++++- 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md index a33b987043f..af5ec44d107 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md @@ -192,6 +192,14 @@ The difference is that when you *construct* a new table, the buffers are transfe Slices will not be supported in MutableTables. +## Table API: Using FieldReaders + +You can get a FieldReader for any vector in the Table using either the Field, vector index, or vector name. The signatures are the same as in VectorSchemaRoot. + +```java +FieldReader nameReader = table.getReader("user_name"); +``` + ## Table API: Row operations Row-based access is supported using a Row object. Row provides *get()* methods by both vector name and vector position, but no *set()* operations. It is important to recognize that it's NOT a reified row, but rather operates like a cursor where the data from numerous logical rows in the Table can be viewed (one row at a time) using the same Row instance. See "Getting around" below for information about how to navigate through the table. @@ -309,6 +317,12 @@ This works by converting the data to a VectorSchemaRoot and using the existing f Data.exportTable(bufferAllocator, table, dictionaryProvider, outArrowArray); ``` +If the table contains dictionary-encoded vectors, it should have been created with a dictionary provider to support encode and decode operations. In that case, the provider argument can be ommitted and the table's provider attribute will be used: + +```java +Data.exportTable(bufferAllocator, table, outArrowArray); +``` + ### Importing Tables from native code ***Current limitation: Data imported from native code using the C-Data-interface cannot be used in a table, because the current implementation of CDataReferenceManager does not support the transfer operation.*** diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java index bb07f417928..3cf8668ac10 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java @@ -38,6 +38,7 @@ import org.apache.arrow.vector.VarCharVector; import org.apache.arrow.vector.VectorSchemaRoot; import org.apache.arrow.vector.dictionary.Dictionary; +import org.apache.arrow.vector.dictionary.DictionaryEncoder; import org.apache.arrow.vector.dictionary.DictionaryProvider; import org.apache.arrow.vector.types.pojo.ArrowType; import org.apache.arrow.vector.types.pojo.DictionaryEncoding; @@ -233,6 +234,42 @@ void testEncode() { } } + @Test + void testDecode() { + List vectorList = intPlusVarcharColumns(allocator); + VarCharVector original = (VarCharVector) vectorList.get(1); + + VarCharVector dictionaryVector = new VarCharVector("dictionary", allocator); + dictionaryVector.allocateNew(2); + dictionaryVector.set(0, "one".getBytes()); + dictionaryVector.set(1, "two".getBytes()); + dictionaryVector.setValueCount(2); + Dictionary dictionary = + new Dictionary(dictionaryVector, new DictionaryEncoding(1L, false, null)); + + DictionaryEncoder encoder = new DictionaryEncoder(dictionary, allocator); + IntVector encoded = (IntVector) encoder.encode(original); + vectorList.remove(original); + vectorList.add(encoded); + DictionaryProvider provider = getDictionary(); + + try (Table t = new Table(vectorList, vectorList.get(0).getValueCount(), provider)) { + VarCharVector v = (VarCharVector) t.decode(encoded.getName(), 1L); + assertNotNull(v); + assertEquals("one", new String(v.get(0))); + assertEquals("two", new String(v.get(1))); + } + } + + @Test + void getProvider() { + List vectorList = intPlusVarcharColumns(allocator); + DictionaryProvider provider = getDictionary(); + try (Table t = new Table(vectorList, vectorList.get(0).getValueCount(), provider)) { + assertEquals(provider, t.getDictionaryProvider()); + } + } + private DictionaryProvider getDictionary() { DictionaryProvider.MapDictionaryProvider provider = diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index 439d34f2109..df7b9f873bd 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -212,7 +212,6 @@ void testSimpleStructVector1() { try (StructVector structVector = simpleStructVector(allocator); VectorSchemaRoot vectorSchemaRoot = VectorSchemaRoot.of(structVector); Table table = new Table(vectorSchemaRoot)) { - System.out.println(table.contentToTSVString()); for (Row c : table) { @SuppressWarnings("unchecked") JsonStringHashMap struct = @@ -283,4 +282,17 @@ void testSimpleMapVector1() { } } } + + @Test + void resetPosition() { + try (ListVector listVector = simpleListVector(allocator); + VectorSchemaRoot vectorSchemaRoot = VectorSchemaRoot.of(listVector); + Table table = new Table(vectorSchemaRoot)) { + Row row = table.immutableRow(); + row.next(); + assertEquals(0, row.rowNumber); + row.resetPosition(); + assertEquals(-1, row.rowNumber); + } + } } From 3ac5effa82953b46709e414a79166a5bdb2f5d13 Mon Sep 17 00:00:00 2001 From: Larry White Date: Fri, 30 Sep 2022 12:47:28 -0400 Subject: [PATCH 09/40] cleanup and additional test for table --- .../org/apache/arrow/vector/table/README.md | 2 +- .../org/apache/arrow/vector/table/Table.java | 10 ------- .../apache/arrow/vector/table/TableTest.java | 29 +++++++++++++++++++ 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md index af5ec44d107..9e99bedf755 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md @@ -338,5 +338,5 @@ The following are the major limitations of v. 10.0.0 release: 1. No support ChunkedArrays or any form of row-group. Support for ChunkedArrows or row groups will be considered for a future release. 2. No support for native interface using the C-Stream API. Support for the streaming API will be delivered with or after Item 1. 3. No ability to use Tables with data imported from native code using the C-Data API. Support for ths feature is gated on PR#13248 (https://github.com/apache/arrow/pull/13248). -4. No support for creating tables directly from Java POJOs. All data held by a table must be imported via a VectorSchemaRoot. +4. No support for creating tables directly from Java POJOs. All data held by a table must be imported via a VectorSchemaRoot, or from collections or arrays of FieldVectors. 5. No support for mutable tables. \ No newline at end of file diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/Table.java b/java/vector/src/main/java/org/apache/arrow/vector/table/Table.java index 49ed8d6f243..37cdf9eb1e2 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/Table.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/Table.java @@ -83,16 +83,6 @@ public Table(List fieldVectors, int rowCount, DictionaryProvider pr super(fieldVectors, rowCount, provider); } - /* - */ - /** Constructs a new instance containing the children of parent but not the parent itself. */ - /* - - public Table(FieldVector parent) { - this(parent.getField().getChildren(), parent.getChildrenFromFields(), parent.getValueCount()); - } - */ - /** * Constructs a new instance containing the data from the argument. Vectors are shared between the * Table and VectorSchemaRoot. Direct modification of those vectors is unsafe and should be diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/TableTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/TableTest.java index 787762f8f56..3667574fe44 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/TableTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/TableTest.java @@ -23,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -98,6 +99,34 @@ void constructor() { } } + /** + * Tests construction with an iterable that's not a list (there is a specialty constructor for Lists) + */ + @Test + void constructor2() { + List vectorList = twoIntColumns(allocator); + Iterable iterable = new HashSet<>(vectorList); + try (Table t = new Table(iterable)) { + assertEquals(2, t.getRowCount()); + assertEquals(2, t.getVectorCount()); + Row c = t.immutableRow(); + IntVector intVector1 = (IntVector) vectorList.get(0); + c.setPosition(0); + + // Now test changes to the first vector + // first Table value is 1 + assertEquals(1, c.getInt(INT_VECTOR_NAME_1)); + + // original vector is updated to set first value to 44 + intVector1.setSafe(0, 44); + assertEquals(44, intVector1.get(0)); + assertEquals(44, ((IntVector) vectorList.get(0)).get(0)); + + // first Table value is still 1 for the zeroth vector + assertEquals(1, c.getInt(INT_VECTOR_NAME_1)); + } + } + @Test void addVector() { List vectorList = twoIntColumns(allocator); From 2a99072dc800fdbb4cdd709ba4552a0005c292ea Mon Sep 17 00:00:00 2001 From: Larry White Date: Sat, 1 Oct 2022 11:46:37 -0400 Subject: [PATCH 10/40] doc and minor tweak to row. --- .../java/org/apache/arrow/vector/table/Row.java | 2 +- .../org/apache/arrow/vector/table/TestUtils.java | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java index 2a3f1a8786d..6593f056809 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java @@ -128,7 +128,7 @@ public Row(BaseTable table) { * Resets the current row to -1 and returns this object. */ @Override - Row resetPosition() { + public Row resetPosition() { return (Row) super.resetPosition(); } diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java b/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java index a8acd180ddd..afb443bd5ed 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java @@ -112,12 +112,25 @@ static List intPlusVarcharColumns(BufferAllocator allocator) { return vectorList; } + /** + * Returns a list of fixed-width vectors for testing. It includes + *

    + *
  1. all integral and floating point types
  2. + *
  3. all basic times and timestamps (second, milli, micro, nano
  4. + *
+ * + * The vector names are based on their type name (e.g. BigIntVector is called "bigInt_vector" + */ static List fixedWidthVectors(BufferAllocator allocator, int rowCount) { List vectors = new ArrayList<>(); numericVectors(vectors, allocator, rowCount); return simpleTemporalVectors(vectors, allocator, rowCount); } + /** + * Returns a list of all integral and floating point vectors. + * The vector names are based on their type name (e.g. BigIntVector is called "bigInt_vector" + */ static List numericVectors( List vectors, BufferAllocator allocator, int rowCount) { vectors.add(new IntVector("int_vector", allocator)); From 1fb975139483875b97af5d665128db064620d107 Mon Sep 17 00:00:00 2001 From: Larry White Date: Sat, 1 Oct 2022 13:04:55 -0400 Subject: [PATCH 11/40] Extended tests to do initial coverage of UInt vectors --- java/pom.xml | 10 ++++++++++ .../java/org/apache/arrow/vector/table/RowTest.java | 9 ++++----- .../java/org/apache/arrow/vector/table/TableTest.java | 2 +- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/java/pom.xml b/java/pom.xml index cdd8fa181de..95e787c1e48 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -43,8 +43,10 @@ 2 true + 3.10.1 @@ -775,9 +777,12 @@ true -XDcompilePolicy=simple + + @@ -810,7 +816,9 @@ UTF-8 -XDcompilePolicy=simple + -J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED @@ -822,6 +830,7 @@ -J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED + diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index df7b9f873bd..3b45efd62a7 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -160,11 +160,10 @@ void fixedWidthVectorTest() { assertEquals(c.getSmallInt("smallInt_vector"), c.getSmallInt(2)); assertEquals(c.getTinyInt("tinyInt_vector"), c.getTinyInt(3)); - // TODO: Uncomment these when GenerateSampleData supports UInts - // assertEquals(c.getUInt1("uInt1_vector"), c.getUInt1(0)); - // assertEquals(c.getUInt2("uInt2_vector"), c.getUInt2(1)); - // assertEquals(c.getUInt4("uInt4_vector"), c.getUInt4(2)); - // assertEquals(c.getUInt8("uInt8_vector"), c.getUInt8(3)); + assertEquals(c.getUInt1("uInt1_vector"), c.getUInt1(4)); + assertEquals(c.getUInt2("uInt2_vector"), c.getUInt2(5)); + assertEquals(c.getUInt4("uInt4_vector"), c.getUInt4(6)); + assertEquals(c.getUInt8("uInt8_vector"), c.getUInt8(7)); assertEquals(c.getFloat4("float4_vector"), c.getFloat4(8)); assertEquals(c.getFloat8("float8_vector"), c.getFloat8(9)); diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/TableTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/TableTest.java index 3667574fe44..ebbab4f57f8 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/TableTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/TableTest.java @@ -100,7 +100,7 @@ void constructor() { } /** - * Tests construction with an iterable that's not a list (there is a specialty constructor for Lists) + * Tests construction with an iterable that's not a list (there is a specialty constructor for Lists). */ @Test void constructor2() { From 016f657a975a5b96fa8f8d963f6f11e9384b76d1 Mon Sep 17 00:00:00 2001 From: Larry White Date: Sat, 1 Oct 2022 13:44:05 -0400 Subject: [PATCH 12/40] Initial set of getter tests using value holders --- .../apache/arrow/vector/table/RowTest.java | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index 3b45efd62a7..23189b16fbf 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -47,6 +47,16 @@ import org.apache.arrow.vector.complex.MapVector; import org.apache.arrow.vector.complex.StructVector; import org.apache.arrow.vector.complex.UnionVector; +import org.apache.arrow.vector.holders.NullableBigIntHolder; +import org.apache.arrow.vector.holders.NullableFloat4Holder; +import org.apache.arrow.vector.holders.NullableFloat8Holder; +import org.apache.arrow.vector.holders.NullableIntHolder; +import org.apache.arrow.vector.holders.NullableSmallIntHolder; +import org.apache.arrow.vector.holders.NullableTinyIntHolder; +import org.apache.arrow.vector.holders.NullableUInt1Holder; +import org.apache.arrow.vector.holders.NullableUInt2Holder; +import org.apache.arrow.vector.holders.NullableUInt4Holder; +import org.apache.arrow.vector.holders.NullableUInt8Holder; import org.apache.arrow.vector.util.JsonStringHashMap; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -154,20 +164,87 @@ void fixedWidthVectorTest() { try (Table t = new Table(vectorList)) { Row c = t.immutableRow(); c.setPosition(1); + // integer tests using vector name and index assertFalse(c.isNull("bigInt_vector")); assertEquals(c.getInt("int_vector"), c.getInt(0)); assertEquals(c.getBigInt("bigInt_vector"), c.getBigInt(1)); assertEquals(c.getSmallInt("smallInt_vector"), c.getSmallInt(2)); assertEquals(c.getTinyInt("tinyInt_vector"), c.getTinyInt(3)); + // integer tests using Nullable Holders + NullableIntHolder int4Holder = new NullableIntHolder(); + NullableTinyIntHolder int1Holder = new NullableTinyIntHolder(); + NullableSmallIntHolder int2Holder = new NullableSmallIntHolder(); + NullableBigIntHolder int8Holder = new NullableBigIntHolder(); + c.getInt(0, int4Holder); + c.getBigInt(1, int8Holder); + c.getSmallInt(2, int2Holder); + c.getTinyInt(3, int1Holder); + assertEquals(c.getInt("int_vector"), int4Holder.value); + assertEquals(c.getBigInt("bigInt_vector"), int8Holder.value); + assertEquals(c.getSmallInt("smallInt_vector"), int2Holder.value); + assertEquals(c.getTinyInt("tinyInt_vector"), int1Holder.value); + + c.getInt("int_vector", int4Holder); + c.getBigInt("bigInt_vector", int8Holder); + c.getSmallInt("smallInt_vector", int2Holder); + c.getTinyInt("tinyInt_vector", int1Holder); + assertEquals(c.getInt("int_vector"), int4Holder.value); + assertEquals(c.getBigInt("bigInt_vector"), int8Holder.value); + assertEquals(c.getSmallInt("smallInt_vector"), int2Holder.value); + assertEquals(c.getTinyInt("tinyInt_vector"), int1Holder.value); + + // uint tests using vector name and index assertEquals(c.getUInt1("uInt1_vector"), c.getUInt1(4)); assertEquals(c.getUInt2("uInt2_vector"), c.getUInt2(5)); assertEquals(c.getUInt4("uInt4_vector"), c.getUInt4(6)); assertEquals(c.getUInt8("uInt8_vector"), c.getUInt8(7)); + // UInt tests using Nullable Holders + NullableUInt4Holder uInt4Holder = new NullableUInt4Holder(); + NullableUInt1Holder uInt1Holder = new NullableUInt1Holder(); + NullableUInt2Holder uInt2Holder = new NullableUInt2Holder(); + NullableUInt8Holder uInt8Holder = new NullableUInt8Holder(); + // fill the holders using vector index and test + c.getUInt1(4, uInt1Holder); + c.getUInt2(5, uInt2Holder); + c.getUInt4(6, uInt4Holder); + c.getUInt8(7, uInt8Holder); + assertEquals(c.getUInt1("uInt1_vector"), uInt1Holder.value); + assertEquals(c.getUInt2("uInt2_vector"), uInt2Holder.value); + assertEquals(c.getUInt4("uInt4_vector"), uInt4Holder.value); + assertEquals(c.getUInt8("uInt8_vector"), uInt8Holder.value); + + // refill the holders using vector name and retest + c.getUInt1("uInt1_vector", uInt1Holder); + c.getUInt2("uInt2_vector", uInt2Holder); + c.getUInt4("uInt4_vector", uInt4Holder); + c.getUInt8("uInt8_vector", uInt8Holder); + assertEquals(c.getUInt1("uInt1_vector"), uInt1Holder.value); + assertEquals(c.getUInt2("uInt2_vector"), uInt2Holder.value); + assertEquals(c.getUInt4("uInt4_vector"), uInt4Holder.value); + assertEquals(c.getUInt8("uInt8_vector"), uInt8Holder.value); + + // tests floating point assertEquals(c.getFloat4("float4_vector"), c.getFloat4(8)); assertEquals(c.getFloat8("float8_vector"), c.getFloat8(9)); + // floating point tests using Nullable Holders + NullableFloat4Holder float4Holder = new NullableFloat4Holder(); + NullableFloat8Holder float8Holder = new NullableFloat8Holder(); + // fill the holders using vector index and test + c.getFloat4(8, float4Holder); + c.getFloat8(9, float8Holder); + assertEquals(c.getFloat4("float4_vector"), float4Holder.value); + assertEquals(c.getFloat8("float8_vector"), float8Holder.value); + + // refill the holders using vector name and retest + c.getFloat4("float4_vector", float4Holder); + c.getFloat8("float8_vector", float8Holder); + assertEquals(c.getFloat4("float4_vector"), float4Holder.value); + assertEquals(c.getFloat8("float8_vector"), float8Holder.value); + + // test time values using vector name versus vector index assertEquals(c.getTimeSec("timeSec_vector"), c.getTimeSec(10)); assertEquals(c.getTimeMilli("timeMilli_vector"), c.getTimeMilli(11)); assertEquals(c.getTimeMicro("timeMicro_vector"), c.getTimeMicro(12)); From 879a3f61fce087c4a39ff76799cfa82aaf5037d7 Mon Sep 17 00:00:00 2001 From: Larry White Date: Sat, 1 Oct 2022 17:36:44 -0400 Subject: [PATCH 13/40] added tests for holders for time and timestamp vector types --- .../apache/arrow/vector/table/RowTest.java | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index 23189b16fbf..29635581c26 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -52,6 +52,14 @@ import org.apache.arrow.vector.holders.NullableFloat8Holder; import org.apache.arrow.vector.holders.NullableIntHolder; import org.apache.arrow.vector.holders.NullableSmallIntHolder; +import org.apache.arrow.vector.holders.NullableTimeMicroHolder; +import org.apache.arrow.vector.holders.NullableTimeMilliHolder; +import org.apache.arrow.vector.holders.NullableTimeNanoHolder; +import org.apache.arrow.vector.holders.NullableTimeSecHolder; +import org.apache.arrow.vector.holders.NullableTimeStampMicroHolder; +import org.apache.arrow.vector.holders.NullableTimeStampMilliHolder; +import org.apache.arrow.vector.holders.NullableTimeStampNanoHolder; +import org.apache.arrow.vector.holders.NullableTimeStampSecHolder; import org.apache.arrow.vector.holders.NullableTinyIntHolder; import org.apache.arrow.vector.holders.NullableUInt1Holder; import org.apache.arrow.vector.holders.NullableUInt2Holder; @@ -250,10 +258,60 @@ void fixedWidthVectorTest() { assertEquals(c.getTimeMicro("timeMicro_vector"), c.getTimeMicro(12)); assertEquals(c.getTimeNano("timeNano_vector"), c.getTimeNano(13)); + // time tests using Nullable Holders + NullableTimeSecHolder timeSecHolder = new NullableTimeSecHolder(); + NullableTimeMilliHolder timeMilliHolder = new NullableTimeMilliHolder(); + NullableTimeMicroHolder timeMicroHolder = new NullableTimeMicroHolder(); + NullableTimeNanoHolder timeNanoHolder = new NullableTimeNanoHolder(); + // fill the holders using vector index and test + c.getTimeSec(10, timeSecHolder); + c.getTimeMilli(11, timeMilliHolder); + c.getTimeMicro(12, timeMicroHolder); + c.getTimeNano(13, timeNanoHolder); + assertEquals(c.getTimeSec("timeSec_vector"), timeSecHolder.value); + assertEquals(c.getTimeMilli("timeMilli_vector"), timeMilliHolder.value); + assertEquals(c.getTimeMicro("timeMicro_vector"), timeMicroHolder.value); + assertEquals(c.getTimeNano("timeNano_vector"), timeNanoHolder.value); + + // refill the holders using vector name and retest + c.getTimeSec("timeSec_vector", timeSecHolder); + c.getTimeMilli("timeMilli_vector", timeMilliHolder); + c.getTimeMicro("timeMicro_vector", timeMicroHolder); + c.getTimeNano("timeNano_vector", timeNanoHolder); + assertEquals(c.getTimeSec("timeSec_vector"), timeSecHolder.value); + assertEquals(c.getTimeMilli("timeMilli_vector"), timeMilliHolder.value); + assertEquals(c.getTimeMicro("timeMicro_vector"), timeMicroHolder.value); + assertEquals(c.getTimeNano("timeNano_vector"), timeNanoHolder.value); + assertEquals(c.getTimeStampSec("timeStampSec_vector"), c.getTimeStampSec(14)); assertEquals(c.getTimeStampMilli("timeStampMilli_vector"), c.getTimeStampMilli(15)); assertEquals(c.getTimeStampMicro("timeStampMicro_vector"), c.getTimeStampMicro(16)); assertEquals(c.getTimeStampNano("timeStampNano_vector"), c.getTimeStampNano(17)); + + // time stamp tests using Nullable Holders + NullableTimeStampSecHolder timeStampSecHolder = new NullableTimeStampSecHolder(); + NullableTimeStampMilliHolder timeStampMilliHolder = new NullableTimeStampMilliHolder(); + NullableTimeStampMicroHolder timeStampMicroHolder = new NullableTimeStampMicroHolder(); + NullableTimeStampNanoHolder timeStampNanoHolder = new NullableTimeStampNanoHolder(); + // fill the holders using vector index and test + c.getTimeStampSec(14, timeStampSecHolder); + c.getTimeStampMilli(15, timeStampMilliHolder); + c.getTimeStampMicro(16, timeStampMicroHolder); + c.getTimeStampNano(17, timeStampNanoHolder); + assertEquals(c.getTimeStampSec("timeStampSec_vector"), timeStampSecHolder.value); + assertEquals(c.getTimeStampMilli("timeStampMilli_vector"), timeStampMilliHolder.value); + assertEquals(c.getTimeStampMicro("timeStampMicro_vector"), timeStampMicroHolder.value); + assertEquals(c.getTimeStampNano("timeStampNano_vector"), timeStampNanoHolder.value); + + // refill the holders using vector name and retest + c.getTimeStampSec("timeStampSec_vector", timeStampSecHolder); + c.getTimeStampMilli("timeStampMilli_vector", timeStampMilliHolder); + c.getTimeStampMicro("timeStampMicro_vector", timeStampMicroHolder); + c.getTimeStampNano("timeStampNano_vector", timeStampNanoHolder); + assertEquals(c.getTimeStampSec("timeStampSec_vector"), timeStampSecHolder.value); + assertEquals(c.getTimeStampMilli("timeStampMilli_vector"), timeStampMilliHolder.value); + assertEquals(c.getTimeStampMicro("timeStampMicro_vector"), timeStampMicroHolder.value); + assertEquals(c.getTimeStampNano("timeStampNano_vector"), timeStampNanoHolder.value); } } From bdc364703b985f99b0f0d4003059b95f365857d0 Mon Sep 17 00:00:00 2001 From: Larry White Date: Sat, 1 Oct 2022 18:05:17 -0400 Subject: [PATCH 14/40] Added tests for varbinary and varchar vectors. Some new test methods and clean-up --- .../apache/arrow/vector/table/RowTest.java | 51 ++++++++++++ .../apache/arrow/vector/table/TestUtils.java | 78 ++++++++++++++++--- 2 files changed, 119 insertions(+), 10 deletions(-) diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index 29635581c26..efb2d0521a3 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -22,13 +22,20 @@ import static org.apache.arrow.vector.table.TestUtils.INT_VECTOR_NAME_1; import static org.apache.arrow.vector.table.TestUtils.STRUCT_VECTOR_NAME; import static org.apache.arrow.vector.table.TestUtils.UNION_VECTOR_NAME; +import static org.apache.arrow.vector.table.TestUtils.VARBINARY_VECTOR_NAME_1; +import static org.apache.arrow.vector.table.TestUtils.VARCHAR_VECTOR_NAME_1; import static org.apache.arrow.vector.table.TestUtils.fixedWidthVectors; +import static org.apache.arrow.vector.table.TestUtils.intPlusLargeVarBinaryColumns; +import static org.apache.arrow.vector.table.TestUtils.intPlusLargeVarcharColumns; +import static org.apache.arrow.vector.table.TestUtils.intPlusVarBinaryColumns; +import static org.apache.arrow.vector.table.TestUtils.intPlusVarcharColumns; import static org.apache.arrow.vector.table.TestUtils.simpleDenseUnionVector; import static org.apache.arrow.vector.table.TestUtils.simpleListVector; import static org.apache.arrow.vector.table.TestUtils.simpleMapVector; import static org.apache.arrow.vector.table.TestUtils.simpleStructVector; import static org.apache.arrow.vector.table.TestUtils.simpleUnionVector; import static org.apache.arrow.vector.table.TestUtils.twoIntColumns; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -315,6 +322,50 @@ void fixedWidthVectorTest() { } } + @Test + void getVarChar() { + List vectorList = intPlusVarcharColumns(allocator); + try (Table t = new Table(vectorList)) { + Row c = t.immutableRow(); + c.setPosition(1); + assertEquals(c.getVarChar(1), "two"); + assertEquals(c.getVarChar(1), c.getVarChar(VARCHAR_VECTOR_NAME_1)); + } + } + + @Test + void getVarBinary() { + List vectorList = intPlusVarBinaryColumns(allocator); + try (Table t = new Table(vectorList)) { + Row c = t.immutableRow(); + c.setPosition(1); + assertArrayEquals(c.getVarBinary(1), "two".getBytes()); + assertArrayEquals(c.getVarBinary(1), c.getVarBinary(VARBINARY_VECTOR_NAME_1)); + } + } + + @Test + void getLargeVarBinary() { + List vectorList = intPlusLargeVarBinaryColumns(allocator); + try (Table t = new Table(vectorList)) { + Row c = t.immutableRow(); + c.setPosition(1); + assertArrayEquals(c.getLargeVarBinary(1), "two".getBytes()); + assertArrayEquals(c.getLargeVarBinary(1), c.getLargeVarBinary(VARBINARY_VECTOR_NAME_1)); + } + } + + @Test + void getLargeVarChar() { + List vectorList = intPlusLargeVarcharColumns(allocator); + try (Table t = new Table(vectorList)) { + Row c = t.immutableRow(); + c.setPosition(1); + assertEquals(c.getLargeVarChar(1), "two"); + assertEquals(c.getLargeVarChar(1), c.getLargeVarChar(VARCHAR_VECTOR_NAME_1)); + } + } + @Test void testSimpleListVector1() { try (ListVector listVector = simpleListVector(allocator); diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java b/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java index afb443bd5ed..ceef6c28a64 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java @@ -30,6 +30,8 @@ import org.apache.arrow.vector.Float8Vector; import org.apache.arrow.vector.GenerateSampleData; import org.apache.arrow.vector.IntVector; +import org.apache.arrow.vector.LargeVarBinaryVector; +import org.apache.arrow.vector.LargeVarCharVector; import org.apache.arrow.vector.SmallIntVector; import org.apache.arrow.vector.TimeMicroVector; import org.apache.arrow.vector.TimeMilliVector; @@ -44,6 +46,7 @@ import org.apache.arrow.vector.UInt2Vector; import org.apache.arrow.vector.UInt4Vector; import org.apache.arrow.vector.UInt8Vector; +import org.apache.arrow.vector.VarBinaryVector; import org.apache.arrow.vector.VarCharVector; import org.apache.arrow.vector.complex.DenseUnionVector; import org.apache.arrow.vector.complex.ListVector; @@ -64,6 +67,7 @@ public class TestUtils { public static final String INT_VECTOR_NAME = "intCol"; public static final String INT_VECTOR_NAME_1 = "intCol1"; public static final String VARCHAR_VECTOR_NAME_1 = "varcharCol1"; + public static final String VARBINARY_VECTOR_NAME_1 = "varbinaryCol1"; public static final String INT_VECTOR_NAME_2 = "intCol2"; public static final String INT_LIST_VECTOR_NAME = "int list vector"; public static final String BIGINT_INT_MAP_VECTOR_NAME = "bigint-int map vector"; @@ -76,11 +80,7 @@ public class TestUtils { */ static List twoIntColumns(BufferAllocator allocator) { List vectorList = new ArrayList<>(); - IntVector v1 = new IntVector(INT_VECTOR_NAME_1, allocator); - v1.allocateNew(2); - v1.set(0, 1); - v1.set(1, 2); - v1.setValueCount(2); + IntVector v1 = getSimpleIntVector(allocator); IntVector v2 = new IntVector(INT_VECTOR_NAME_2, allocator); v2.allocateNew(2); v2.set(0, 3); @@ -97,11 +97,7 @@ static List twoIntColumns(BufferAllocator allocator) { */ static List intPlusVarcharColumns(BufferAllocator allocator) { List vectorList = new ArrayList<>(); - IntVector v1 = new IntVector(INT_VECTOR_NAME_1, allocator); - v1.allocateNew(2); - v1.set(0, 1); - v1.set(1, 2); - v1.setValueCount(2); + IntVector v1 = getSimpleIntVector(allocator); VarCharVector v2 = new VarCharVector(VARCHAR_VECTOR_NAME_1, allocator); v2.allocateNew(2); v2.set(0, "one".getBytes()); @@ -112,6 +108,68 @@ static List intPlusVarcharColumns(BufferAllocator allocator) { return vectorList; } + /** + * Returns a list of two FieldVectors to be used to instantiate Tables for testing. The first + * vector is an IntVector and the second is a LargeVarCharVector. Each vector has two values set. + */ + static List intPlusLargeVarcharColumns(BufferAllocator allocator) { + List vectorList = new ArrayList<>(); + IntVector v1 = getSimpleIntVector(allocator); + LargeVarCharVector v2 = new LargeVarCharVector(VARCHAR_VECTOR_NAME_1, allocator); + v2.allocateNew(2); + v2.set(0, "one".getBytes()); + v2.set(1, "two".getBytes()); + v2.setValueCount(2); + vectorList.add(v1); + vectorList.add(v2); + return vectorList; + } + + /** + * Returns a list of two FieldVectors to be used to instantiate Tables for testing. The first + * vector is an IntVector and the second is a VarBinaryVector. Each vector has two values set. + * The large binary vectors values are "one" and "two" encoded with UTF-8 + */ + static List intPlusVarBinaryColumns(BufferAllocator allocator) { + List vectorList = new ArrayList<>(); + IntVector v1 = getSimpleIntVector(allocator); + VarBinaryVector v2 = new VarBinaryVector(VARBINARY_VECTOR_NAME_1, allocator); + v2.allocateNew(2); + v2.set(0, "one".getBytes()); + v2.set(1, "two".getBytes()); + v2.setValueCount(2); + vectorList.add(v1); + vectorList.add(v2); + return vectorList; + } + + /** + * Returns a list of two FieldVectors to be used to instantiate Tables for testing. The first + * vector is an IntVector and the second is a VarBinaryVector. Each vector has two values set. + * The large binary vectors values are "one" and "two" encoded with UTF-8 + */ + static List intPlusLargeVarBinaryColumns(BufferAllocator allocator) { + List vectorList = new ArrayList<>(); + IntVector v1 = getSimpleIntVector(allocator); + LargeVarBinaryVector v2 = new LargeVarBinaryVector(VARBINARY_VECTOR_NAME_1, allocator); + v2.allocateNew(2); + v2.set(0, "one".getBytes()); + v2.set(1, "two".getBytes()); + v2.setValueCount(2); + vectorList.add(v1); + vectorList.add(v2); + return vectorList; + } + + private static IntVector getSimpleIntVector(BufferAllocator allocator) { + IntVector v1 = new IntVector(INT_VECTOR_NAME_1, allocator); + v1.allocateNew(2); + v1.set(0, 1); + v1.set(1, 2); + v1.setValueCount(2); + return v1; + } + /** * Returns a list of fixed-width vectors for testing. It includes *
    From c5fefa5f11f3bb96aae839a6ccdd3262e58221a9 Mon Sep 17 00:00:00 2001 From: Larry White Date: Sun, 2 Oct 2022 13:19:14 -0400 Subject: [PATCH 15/40] more Row tests --- .../org/apache/arrow/vector/table/Row.java | 21 ++++++++++ .../apache/arrow/vector/table/RowTest.java | 42 +++++++++++++++++++ .../apache/arrow/vector/table/TestUtils.java | 24 ++++++++++- 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java index 6593f056809..e1a21fc8a2c 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java @@ -68,6 +68,7 @@ import org.apache.arrow.vector.complex.UnionVector; import org.apache.arrow.vector.holders.NullableBigIntHolder; import org.apache.arrow.vector.holders.NullableBitHolder; +import org.apache.arrow.vector.holders.NullableDecimalHolder; import org.apache.arrow.vector.holders.NullableDurationHolder; import org.apache.arrow.vector.holders.NullableFloat4Holder; import org.apache.arrow.vector.holders.NullableFloat8Holder; @@ -1524,6 +1525,26 @@ public int getIntervalYear(int columnIndex) { return vector.get(rowNumber); } + /** + * Updates the value of the holder with data from vector at the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getDecimal(int columnIndex, NullableDecimalHolder holder) { + DecimalVector vector = (DecimalVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + + /** + * Updates the value of the holder with data from the vector with given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getDecimal(String columnName, NullableDecimalHolder holder) { + DecimalVector vector = (DecimalVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + /** * Returns a BigDecimal from the column of the given name at the current row. An * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index efb2d0521a3..833f825c5cb 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -18,6 +18,7 @@ package org.apache.arrow.vector.table; import static org.apache.arrow.vector.table.TestUtils.BIGINT_INT_MAP_VECTOR_NAME; +import static org.apache.arrow.vector.table.TestUtils.FIXEDBINARY_VECTOR_NAME_1; import static org.apache.arrow.vector.table.TestUtils.INT_LIST_VECTOR_NAME; import static org.apache.arrow.vector.table.TestUtils.INT_VECTOR_NAME_1; import static org.apache.arrow.vector.table.TestUtils.STRUCT_VECTOR_NAME; @@ -25,6 +26,7 @@ import static org.apache.arrow.vector.table.TestUtils.VARBINARY_VECTOR_NAME_1; import static org.apache.arrow.vector.table.TestUtils.VARCHAR_VECTOR_NAME_1; import static org.apache.arrow.vector.table.TestUtils.fixedWidthVectors; +import static org.apache.arrow.vector.table.TestUtils.intPlusFixedBinaryColumns; import static org.apache.arrow.vector.table.TestUtils.intPlusLargeVarBinaryColumns; import static org.apache.arrow.vector.table.TestUtils.intPlusLargeVarcharColumns; import static org.apache.arrow.vector.table.TestUtils.intPlusVarBinaryColumns; @@ -42,11 +44,14 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.math.BigDecimal; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.List; import org.apache.arrow.memory.BufferAllocator; import org.apache.arrow.memory.RootAllocator; +import org.apache.arrow.vector.DecimalVector; import org.apache.arrow.vector.FieldVector; import org.apache.arrow.vector.VectorSchemaRoot; import org.apache.arrow.vector.complex.DenseUnionVector; @@ -55,6 +60,7 @@ import org.apache.arrow.vector.complex.StructVector; import org.apache.arrow.vector.complex.UnionVector; import org.apache.arrow.vector.holders.NullableBigIntHolder; +import org.apache.arrow.vector.holders.NullableDecimalHolder; import org.apache.arrow.vector.holders.NullableFloat4Holder; import org.apache.arrow.vector.holders.NullableFloat8Holder; import org.apache.arrow.vector.holders.NullableIntHolder; @@ -131,6 +137,31 @@ void getIntByVectorName() { } } + + @Test + void getDecimal() { + List vectors = new ArrayList<>(); + DecimalVector decimalVector = new DecimalVector("decimal_vector", allocator, 55, 10); + vectors.add(decimalVector); + decimalVector.setSafe(0, new BigDecimal("0.0543278923")); + decimalVector.setSafe(1, new BigDecimal("2.0543278923")); + decimalVector.setValueCount(2); + BigDecimal one = decimalVector.getObject(1); + + NullableDecimalHolder holder1 = new NullableDecimalHolder(); + NullableDecimalHolder holder2 = new NullableDecimalHolder(); + try (Table t = new Table(vectors)) { + Row c = t.immutableRow(); + c.setPosition(1); + assertEquals(one, c.getDecimalObj("decimal_vector")); + assertEquals(one, c.getDecimalObj(0)); + c.getDecimal(0, holder1); + c.getDecimal("decimal_vector", holder2); + assertEquals(holder1.buffer, holder2.buffer); + assertEquals(c.getDecimal(0).memoryAddress(), c.getDecimal("decimal_vector").memoryAddress()); + } + } + @Test void hasNext() { List vectorList = twoIntColumns(allocator); @@ -366,6 +397,17 @@ void getLargeVarChar() { } } + @Test + void getFixedBinary() { + List vectorList = intPlusFixedBinaryColumns(allocator); + try (Table t = new Table(vectorList)) { + Row c = t.immutableRow(); + c.setPosition(1); + assertArrayEquals(c.getFixedSizeBinary(1), "two".getBytes()); + assertArrayEquals(c.getFixedSizeBinary(1), c.getFixedSizeBinary(FIXEDBINARY_VECTOR_NAME_1)); + } + } + @Test void testSimpleListVector1() { try (ListVector listVector = simpleListVector(allocator); diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java b/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java index ceef6c28a64..616b7a803d5 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java @@ -25,7 +25,9 @@ import org.apache.arrow.memory.BufferAllocator; import org.apache.arrow.vector.BigIntVector; import org.apache.arrow.vector.BitVectorHelper; +import org.apache.arrow.vector.DecimalVector; import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.FixedSizeBinaryVector; import org.apache.arrow.vector.Float4Vector; import org.apache.arrow.vector.Float8Vector; import org.apache.arrow.vector.GenerateSampleData; @@ -68,6 +70,7 @@ public class TestUtils { public static final String INT_VECTOR_NAME_1 = "intCol1"; public static final String VARCHAR_VECTOR_NAME_1 = "varcharCol1"; public static final String VARBINARY_VECTOR_NAME_1 = "varbinaryCol1"; + public static final String FIXEDBINARY_VECTOR_NAME_1 = "varbinaryCol1"; public static final String INT_VECTOR_NAME_2 = "intCol2"; public static final String INT_LIST_VECTOR_NAME = "int list vector"; public static final String BIGINT_INT_MAP_VECTOR_NAME = "bigint-int map vector"; @@ -161,6 +164,24 @@ static List intPlusLargeVarBinaryColumns(BufferAllocator allocator) return vectorList; } + /** + * Returns a list of two FieldVectors to be used to instantiate Tables for testing. The first + * vector is an IntVector and the second is a FixedSizeBinary vector. Each vector has two values set. + * The large binary vectors values are "one" and "two" encoded with UTF-8 + */ + static List intPlusFixedBinaryColumns(BufferAllocator allocator) { + List vectorList = new ArrayList<>(); + IntVector v1 = getSimpleIntVector(allocator); + FixedSizeBinaryVector v2 = new FixedSizeBinaryVector(FIXEDBINARY_VECTOR_NAME_1, allocator, 3); + v2.allocateNew(2); + v2.set(0, "one".getBytes()); + v2.set(1, "two".getBytes()); + v2.setValueCount(2); + vectorList.add(v1); + vectorList.add(v2); + return vectorList; + } + private static IntVector getSimpleIntVector(BufferAllocator allocator) { IntVector v1 = new IntVector(INT_VECTOR_NAME_1, allocator); v1.allocateNew(2); @@ -182,7 +203,8 @@ private static IntVector getSimpleIntVector(BufferAllocator allocator) { static List fixedWidthVectors(BufferAllocator allocator, int rowCount) { List vectors = new ArrayList<>(); numericVectors(vectors, allocator, rowCount); - return simpleTemporalVectors(vectors, allocator, rowCount); + simpleTemporalVectors(vectors, allocator, rowCount); + return vectors; } /** From 98ce8f2c31cd741b09681b04d4bc8c05b6fc3fd8 Mon Sep 17 00:00:00 2001 From: Larry White Date: Sun, 2 Oct 2022 13:37:14 -0400 Subject: [PATCH 16/40] added tests for duration vectors --- .../apache/arrow/vector/table/RowTest.java | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index 833f825c5cb..40ba55a22e9 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -46,12 +46,14 @@ import java.math.BigDecimal; import java.nio.charset.StandardCharsets; +import java.time.Duration; import java.util.ArrayList; import java.util.List; import org.apache.arrow.memory.BufferAllocator; import org.apache.arrow.memory.RootAllocator; import org.apache.arrow.vector.DecimalVector; +import org.apache.arrow.vector.DurationVector; import org.apache.arrow.vector.FieldVector; import org.apache.arrow.vector.VectorSchemaRoot; import org.apache.arrow.vector.complex.DenseUnionVector; @@ -61,6 +63,7 @@ import org.apache.arrow.vector.complex.UnionVector; import org.apache.arrow.vector.holders.NullableBigIntHolder; import org.apache.arrow.vector.holders.NullableDecimalHolder; +import org.apache.arrow.vector.holders.NullableDurationHolder; import org.apache.arrow.vector.holders.NullableFloat4Holder; import org.apache.arrow.vector.holders.NullableFloat8Holder; import org.apache.arrow.vector.holders.NullableIntHolder; @@ -78,6 +81,9 @@ import org.apache.arrow.vector.holders.NullableUInt2Holder; import org.apache.arrow.vector.holders.NullableUInt4Holder; import org.apache.arrow.vector.holders.NullableUInt8Holder; +import org.apache.arrow.vector.types.TimeUnit; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.FieldType; import org.apache.arrow.vector.util.JsonStringHashMap; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -137,7 +143,6 @@ void getIntByVectorName() { } } - @Test void getDecimal() { List vectors = new ArrayList<>(); @@ -162,6 +167,39 @@ void getDecimal() { } } + @Test + void getDuration() { + List vectors = new ArrayList<>(); + TimeUnit unit = TimeUnit.SECOND; + final FieldType fieldType = FieldType.nullable(new ArrowType.Duration(unit)); + + DurationVector durationVector = new DurationVector("duration_vector", fieldType, allocator); + NullableDurationHolder holder1 = new NullableDurationHolder(); + NullableDurationHolder holder2 = new NullableDurationHolder(); + + holder1.value = 100; + holder1.unit = TimeUnit.SECOND; + holder2.value = 200; + holder2.unit = TimeUnit.SECOND; + + vectors.add(durationVector); + durationVector.setSafe(0, holder1); + durationVector.setSafe(1, holder2); + durationVector.setValueCount(2); + + Duration one = durationVector.getObject(1); + try (Table t = new Table(vectors)) { + Row c = t.immutableRow(); + c.setPosition(1); + assertEquals(one, c.getDurationObj("duration_vector")); + assertEquals(one, c.getDurationObj(0)); + c.getDuration(0, holder1); + c.getDuration("duration_vector", holder2); + assertEquals(holder1.value + 100, holder2.value); + // TODO: FIXME assertEquals(c.getDuration(0).memoryAddress(), c.getDuration("duration_vector").memoryAddress()); + } + } + @Test void hasNext() { List vectorList = twoIntColumns(allocator); From a34dc6fef4d254317f2797eb2519bb970564e281 Mon Sep 17 00:00:00 2001 From: Larry White Date: Sun, 2 Oct 2022 14:08:18 -0400 Subject: [PATCH 17/40] Minor improvements in testing timestamp vectors --- .../org/apache/arrow/vector/table/RowTest.java | 6 ++++++ .../org/apache/arrow/vector/table/TestUtils.java | 15 ++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index 40ba55a22e9..3b7ea30efc8 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -47,6 +47,7 @@ import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.time.Duration; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -379,6 +380,10 @@ void fixedWidthVectorTest() { assertEquals(c.getTimeStampMicro("timeStampMicro_vector"), timeStampMicroHolder.value); assertEquals(c.getTimeStampNano("timeStampNano_vector"), timeStampNanoHolder.value); + LocalDateTime microDT = c.getTimeStampMicroObj(16); + assertNotNull(microDT); + assertEquals(microDT, c.getTimeStampMicroObj("timeStampMicro_vector")); + // refill the holders using vector name and retest c.getTimeStampSec("timeStampSec_vector", timeStampSecHolder); c.getTimeStampMilli("timeStampMilli_vector", timeStampMilliHolder); @@ -391,6 +396,7 @@ void fixedWidthVectorTest() { } } + @Test void getVarChar() { List vectorList = intPlusVarcharColumns(allocator); diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java b/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java index 616b7a803d5..f63f0c89971 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java @@ -25,7 +25,6 @@ import org.apache.arrow.memory.BufferAllocator; import org.apache.arrow.vector.BigIntVector; import org.apache.arrow.vector.BitVectorHelper; -import org.apache.arrow.vector.DecimalVector; import org.apache.arrow.vector.FieldVector; import org.apache.arrow.vector.FixedSizeBinaryVector; import org.apache.arrow.vector.Float4Vector; @@ -39,9 +38,13 @@ import org.apache.arrow.vector.TimeMilliVector; import org.apache.arrow.vector.TimeNanoVector; import org.apache.arrow.vector.TimeSecVector; +import org.apache.arrow.vector.TimeStampMicroTZVector; import org.apache.arrow.vector.TimeStampMicroVector; +import org.apache.arrow.vector.TimeStampMilliTZVector; import org.apache.arrow.vector.TimeStampMilliVector; +import org.apache.arrow.vector.TimeStampNanoTZVector; import org.apache.arrow.vector.TimeStampNanoVector; +import org.apache.arrow.vector.TimeStampSecTZVector; import org.apache.arrow.vector.TimeStampSecVector; import org.apache.arrow.vector.TinyIntVector; import org.apache.arrow.vector.UInt1Vector; @@ -253,6 +256,16 @@ static List simpleTemporalVectors(BufferAllocator allocator, int ro return simpleTemporalVectors(vectors, allocator, rowCount); } + static List timezoneTemporalVectors(BufferAllocator allocator, int rowCount) { + List vectors = new ArrayList<>(); + vectors.add(new TimeStampSecTZVector("timeStampSecTz_vector", allocator, "UTC")); + vectors.add(new TimeStampMilliTZVector("timeStampMilliTz_vector", allocator, "UTC")); + vectors.add(new TimeStampMicroTZVector("timeStampMicroTz_vector", allocator, "UTC")); + vectors.add(new TimeStampNanoTZVector("timeStampNanoTz_vector", allocator, "UTC")); + vectors.forEach(vec -> GenerateSampleData.generateTestData(vec, rowCount)); + return vectors; + } + /** Returns a list vector of ints. */ static ListVector simpleListVector(BufferAllocator allocator) { ListVector listVector = ListVector.empty(INT_LIST_VECTOR_NAME, allocator); From 8631e68a82225ffb9471969ac4053e39e6ed17ec Mon Sep 17 00:00:00 2001 From: Larry White Date: Sun, 2 Oct 2022 19:11:51 -0400 Subject: [PATCH 18/40] Added tests for bitvector --- .../apache/arrow/vector/table/RowTest.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index 3b7ea30efc8..cd597ddf478 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -53,6 +53,7 @@ import org.apache.arrow.memory.BufferAllocator; import org.apache.arrow.memory.RootAllocator; +import org.apache.arrow.vector.BitVector; import org.apache.arrow.vector.DecimalVector; import org.apache.arrow.vector.DurationVector; import org.apache.arrow.vector.FieldVector; @@ -63,6 +64,7 @@ import org.apache.arrow.vector.complex.StructVector; import org.apache.arrow.vector.complex.UnionVector; import org.apache.arrow.vector.holders.NullableBigIntHolder; +import org.apache.arrow.vector.holders.NullableBitHolder; import org.apache.arrow.vector.holders.NullableDecimalHolder; import org.apache.arrow.vector.holders.NullableDurationHolder; import org.apache.arrow.vector.holders.NullableFloat4Holder; @@ -201,6 +203,31 @@ void getDuration() { } } + @Test + void getBit() { + List vectors = new ArrayList<>(); + + BitVector bitVector = new BitVector("bit_vector", allocator); + NullableBitHolder holder1 = new NullableBitHolder(); + NullableBitHolder holder2 = new NullableBitHolder(); + + vectors.add(bitVector); + bitVector.setSafe(0, 0); + bitVector.setSafe(1, 1); + bitVector.setValueCount(2); + + int one = bitVector.get(1); + try (Table t = new Table(vectors)) { + Row c = t.immutableRow(); + c.setPosition(1); + assertEquals(one, c.getBit("bit_vector")); + assertEquals(one, c.getBit(0)); + c.getBit(0, holder1); + c.getBit("bit_vector", holder2); + assertEquals(holder1.value, holder2.value); + } + } + @Test void hasNext() { List vectorList = twoIntColumns(allocator); From c225f5c315dad5d1f1805096b3b8c7725320da8c Mon Sep 17 00:00:00 2001 From: Larry White Date: Sun, 2 Oct 2022 19:15:20 -0400 Subject: [PATCH 19/40] added tests for time milli vector --- .../src/test/java/org/apache/arrow/vector/table/RowTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index cd597ddf478..77ad09e857f 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -377,6 +377,10 @@ void fixedWidthVectorTest() { assertEquals(c.getTimeMicro("timeMicro_vector"), timeMicroHolder.value); assertEquals(c.getTimeNano("timeNano_vector"), timeNanoHolder.value); + LocalDateTime milliDT = c.getTimeMilliObj(11); + assertNotNull(milliDT); + assertEquals(milliDT, c.getTimeMilliObj("timeMilli_vector")); + // refill the holders using vector name and retest c.getTimeSec("timeSec_vector", timeSecHolder); c.getTimeMilli("timeMilli_vector", timeMilliHolder); From 77e5a646f2970f0ee084c2874d647d15e9576e8d Mon Sep 17 00:00:00 2001 From: Larry White Date: Sun, 2 Oct 2022 19:51:38 -0400 Subject: [PATCH 20/40] additional time vector tests --- .../java/org/apache/arrow/vector/table/RowTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index 77ad09e857f..0f8cbf39eae 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -411,10 +411,22 @@ void fixedWidthVectorTest() { assertEquals(c.getTimeStampMicro("timeStampMicro_vector"), timeStampMicroHolder.value); assertEquals(c.getTimeStampNano("timeStampNano_vector"), timeStampNanoHolder.value); + LocalDateTime secDT = c.getTimeStampSecObj(14); + assertNotNull(secDT); + assertEquals(secDT, c.getTimeStampSecObj("timeStampSec_vector")); + + LocalDateTime milliDT1 = c.getTimeStampMilliObj(15); + assertNotNull(milliDT1); + assertEquals(milliDT1, c.getTimeStampMilliObj("timeStampMilli_vector")); + LocalDateTime microDT = c.getTimeStampMicroObj(16); assertNotNull(microDT); assertEquals(microDT, c.getTimeStampMicroObj("timeStampMicro_vector")); + LocalDateTime nanoDT = c.getTimeStampNanoObj(17); + assertNotNull(nanoDT); + assertEquals(nanoDT, c.getTimeStampNanoObj("timeStampNano_vector")); + // refill the holders using vector name and retest c.getTimeStampSec("timeStampSec_vector", timeStampSecHolder); c.getTimeStampMilli("timeStampMilli_vector", timeStampMilliHolder); From 4439648f675a1848e2be982af49e0d6fc327c3ad Mon Sep 17 00:00:00 2001 From: Larry White Date: Mon, 3 Oct 2022 15:22:51 -0400 Subject: [PATCH 21/40] add support for timestamp with TZ tests and some additional duration testing --- .../org/apache/arrow/vector/table/Row.java | 4 +- .../apache/arrow/vector/table/RowTest.java | 60 ++++++++++++++++++- .../apache/arrow/vector/table/TestUtils.java | 8 +-- 3 files changed, 64 insertions(+), 8 deletions(-) diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java index e1a21fc8a2c..578fa518e88 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java @@ -1325,7 +1325,7 @@ public Duration getDurationObj(int columnIndex) { } /** - * Returns a Duration from the column of the given name at the current row. An + * Returns an ArrowBuf from the column of the given name at the current row. An * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException * is thrown if it is present but has a different type */ @@ -1335,7 +1335,7 @@ public ArrowBuf getDuration(String columnName) { } /** - * Returns a Duration from the column with the given index at the current row. An + * Returns an ArrowBuf from the column with the given index at the current row. An * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException * is thrown if it is present but has a different type */ diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index 0f8cbf39eae..002ea1fc42e 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -36,6 +36,7 @@ import static org.apache.arrow.vector.table.TestUtils.simpleMapVector; import static org.apache.arrow.vector.table.TestUtils.simpleStructVector; import static org.apache.arrow.vector.table.TestUtils.simpleUnionVector; +import static org.apache.arrow.vector.table.TestUtils.timezoneTemporalVectors; import static org.apache.arrow.vector.table.TestUtils.twoIntColumns; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -51,6 +52,7 @@ import java.util.ArrayList; import java.util.List; +import org.apache.arrow.memory.ArrowBuf; import org.apache.arrow.memory.BufferAllocator; import org.apache.arrow.memory.RootAllocator; import org.apache.arrow.vector.BitVector; @@ -76,9 +78,13 @@ import org.apache.arrow.vector.holders.NullableTimeNanoHolder; import org.apache.arrow.vector.holders.NullableTimeSecHolder; import org.apache.arrow.vector.holders.NullableTimeStampMicroHolder; +import org.apache.arrow.vector.holders.NullableTimeStampMicroTZHolder; import org.apache.arrow.vector.holders.NullableTimeStampMilliHolder; +import org.apache.arrow.vector.holders.NullableTimeStampMilliTZHolder; import org.apache.arrow.vector.holders.NullableTimeStampNanoHolder; +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.NullableTinyIntHolder; import org.apache.arrow.vector.holders.NullableUInt1Holder; import org.apache.arrow.vector.holders.NullableUInt2Holder; @@ -182,8 +188,10 @@ void getDuration() { holder1.value = 100; holder1.unit = TimeUnit.SECOND; + holder1.isSet = 1; holder2.value = 200; holder2.unit = TimeUnit.SECOND; + holder2.isSet = 1; vectors.add(durationVector); durationVector.setSafe(0, holder1); @@ -198,8 +206,10 @@ void getDuration() { assertEquals(one, c.getDurationObj(0)); c.getDuration(0, holder1); c.getDuration("duration_vector", holder2); - assertEquals(holder1.value + 100, holder2.value); - // TODO: FIXME assertEquals(c.getDuration(0).memoryAddress(), c.getDuration("duration_vector").memoryAddress()); + assertEquals(holder1.value, holder2.value); + ArrowBuf durationBuf1 = c.getDuration(0); + ArrowBuf durationBuf2 = c.getDuration("duration_vector"); + assertEquals(durationBuf1.memoryAddress(), durationBuf2.memoryAddress()); } } @@ -439,6 +449,52 @@ void fixedWidthVectorTest() { } } + @Test + void timestampsWithTimezones() { + List vectorList = timezoneTemporalVectors(allocator, 2); + try (Table t = new Table(vectorList)) { + Row c = t.immutableRow(); + c.setPosition(1); + + assertEquals(c.getTimeStampSecTZ("timeStampSecTZ_vector"), c.getTimeStampSecTZ(0)); + assertEquals(c.getTimeStampMilliTZ("timeStampMilliTZ_vector"), c.getTimeStampMilliTZ(1)); + assertEquals(c.getTimeStampMicroTZ("timeStampMicroTZ_vector"), c.getTimeStampMicroTZ(2)); + assertEquals(c.getTimeStampNanoTZ("timeStampNanoTZ_vector"), c.getTimeStampNanoTZ(3)); + + // time stamp tests using Nullable Holders + NullableTimeStampSecTZHolder timeStampSecHolder = new NullableTimeStampSecTZHolder(); + NullableTimeStampMilliTZHolder timeStampMilliHolder = new NullableTimeStampMilliTZHolder(); + NullableTimeStampMicroTZHolder timeStampMicroHolder = new NullableTimeStampMicroTZHolder(); + NullableTimeStampNanoTZHolder timeStampNanoHolder = new NullableTimeStampNanoTZHolder(); + + // fill the holders using vector index and test + c.getTimeStampSecTZ(0, timeStampSecHolder); + c.getTimeStampMilliTZ(1, timeStampMilliHolder); + c.getTimeStampMicroTZ(2, timeStampMicroHolder); + c.getTimeStampNanoTZ(3, timeStampNanoHolder); + + long tsSec = timeStampSecHolder.value; + long tsMil = timeStampMilliHolder.value; + long tsMic = timeStampMicroHolder.value; + long tsNan = timeStampNanoHolder.value; + + assertEquals(c.getTimeStampSecTZ("timeStampSecTZ_vector"), timeStampSecHolder.value); + assertEquals(c.getTimeStampMilliTZ("timeStampMilliTZ_vector"), timeStampMilliHolder.value); + assertEquals(c.getTimeStampMicroTZ("timeStampMicroTZ_vector"), timeStampMicroHolder.value); + assertEquals(c.getTimeStampNanoTZ("timeStampNanoTZ_vector"), timeStampNanoHolder.value); + + // fill the holders using vector index and test + c.getTimeStampSecTZ("timeStampSecTZ_vector", timeStampSecHolder); + c.getTimeStampMilliTZ("timeStampMilliTZ_vector", timeStampMilliHolder); + c.getTimeStampMicroTZ("timeStampMicroTZ_vector", timeStampMicroHolder); + c.getTimeStampNanoTZ("timeStampNanoTZ_vector", timeStampNanoHolder); + + assertEquals(tsSec, timeStampSecHolder.value); + assertEquals(tsMil, timeStampMilliHolder.value); + assertEquals(tsMic, timeStampMicroHolder.value); + assertEquals(tsNan, timeStampNanoHolder.value); + } + } @Test void getVarChar() { diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java b/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java index f63f0c89971..b64f8b1a057 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/TestUtils.java @@ -258,10 +258,10 @@ static List simpleTemporalVectors(BufferAllocator allocator, int ro static List timezoneTemporalVectors(BufferAllocator allocator, int rowCount) { List vectors = new ArrayList<>(); - vectors.add(new TimeStampSecTZVector("timeStampSecTz_vector", allocator, "UTC")); - vectors.add(new TimeStampMilliTZVector("timeStampMilliTz_vector", allocator, "UTC")); - vectors.add(new TimeStampMicroTZVector("timeStampMicroTz_vector", allocator, "UTC")); - vectors.add(new TimeStampNanoTZVector("timeStampNanoTz_vector", allocator, "UTC")); + vectors.add(new TimeStampSecTZVector("timeStampSecTZ_vector", allocator, "UTC")); + vectors.add(new TimeStampMilliTZVector("timeStampMilliTZ_vector", allocator, "UTC")); + vectors.add(new TimeStampMicroTZVector("timeStampMicroTZ_vector", allocator, "UTC")); + vectors.add(new TimeStampNanoTZVector("timeStampNanoTZ_vector", allocator, "UTC")); vectors.forEach(vec -> GenerateSampleData.generateTestData(vec, rowCount)); return vectors; } From 33b70db5e8e77ea6256696edabc05f81de047ff7 Mon Sep 17 00:00:00 2001 From: Larry White Date: Mon, 3 Oct 2022 15:34:09 -0400 Subject: [PATCH 22/40] Added tests for interval day vectors --- .../apache/arrow/vector/table/RowTest.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index 002ea1fc42e..115f9aba705 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -59,6 +59,7 @@ import org.apache.arrow.vector.DecimalVector; import org.apache.arrow.vector.DurationVector; import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.IntervalDayVector; import org.apache.arrow.vector.VectorSchemaRoot; import org.apache.arrow.vector.complex.DenseUnionVector; import org.apache.arrow.vector.complex.ListVector; @@ -72,6 +73,7 @@ import org.apache.arrow.vector.holders.NullableFloat4Holder; import org.apache.arrow.vector.holders.NullableFloat8Holder; import org.apache.arrow.vector.holders.NullableIntHolder; +import org.apache.arrow.vector.holders.NullableIntervalDayHolder; import org.apache.arrow.vector.holders.NullableSmallIntHolder; import org.apache.arrow.vector.holders.NullableTimeMicroHolder; import org.apache.arrow.vector.holders.NullableTimeMilliHolder; @@ -90,6 +92,7 @@ import org.apache.arrow.vector.holders.NullableUInt2Holder; import org.apache.arrow.vector.holders.NullableUInt4Holder; import org.apache.arrow.vector.holders.NullableUInt8Holder; +import org.apache.arrow.vector.types.IntervalUnit; import org.apache.arrow.vector.types.TimeUnit; import org.apache.arrow.vector.types.pojo.ArrowType; import org.apache.arrow.vector.types.pojo.FieldType; @@ -213,6 +216,44 @@ void getDuration() { } } + @Test + void getIntervalDay() { + List vectors = new ArrayList<>(); + IntervalUnit unit = IntervalUnit.DAY_TIME; + final FieldType fieldType = FieldType.nullable(new ArrowType.Interval(unit)); + + IntervalDayVector intervalDayVector = new IntervalDayVector("intervalDay_vector", fieldType, allocator); + NullableIntervalDayHolder holder1 = new NullableIntervalDayHolder(); + NullableIntervalDayHolder holder2 = new NullableIntervalDayHolder(); + + holder1.days = 100; + holder1.milliseconds = 1000; + holder1.isSet = 1; + holder2.days = 200; + holder2.milliseconds = 2000; + holder2.isSet = 1; + + vectors.add(intervalDayVector); + intervalDayVector.setSafe(0, holder1); + intervalDayVector.setSafe(1, holder2); + intervalDayVector.setValueCount(2); + + Duration one = intervalDayVector.getObject(1); + try (Table t = new Table(vectors)) { + Row c = t.immutableRow(); + c.setPosition(1); + assertEquals(one, c.getIntervalDayObj("intervalDay_vector")); + assertEquals(one, c.getIntervalDayObj(0)); + c.getIntervalDay(0, holder1); + c.getIntervalDay("intervalDay_vector", holder2); + assertEquals(holder1.days, holder2.days); + assertEquals(holder1.milliseconds, holder2.milliseconds); + ArrowBuf intDayBuf1 = c.getIntervalDay(0); + ArrowBuf intDayBuf2 = c.getIntervalDay("intervalDay_vector"); + assertEquals(intDayBuf1.memoryAddress(), intDayBuf2.memoryAddress()); + } + } + @Test void getBit() { List vectors = new ArrayList<>(); From bdc21117dbafe4de6d27034bf77607a90b8534fd Mon Sep 17 00:00:00 2001 From: Larry White Date: Mon, 3 Oct 2022 15:54:21 -0400 Subject: [PATCH 23/40] tests for interval month and year vectors --- .../org/apache/arrow/vector/table/Row.java | 21 +++++ .../apache/arrow/vector/table/RowTest.java | 80 +++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java index 578fa518e88..a75ef3b92c4 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java @@ -75,6 +75,7 @@ import org.apache.arrow.vector.holders.NullableIntHolder; import org.apache.arrow.vector.holders.NullableIntervalDayHolder; import org.apache.arrow.vector.holders.NullableIntervalMonthDayNanoHolder; +import org.apache.arrow.vector.holders.NullableIntervalYearHolder; import org.apache.arrow.vector.holders.NullableSmallIntHolder; import org.apache.arrow.vector.holders.NullableTimeMicroHolder; import org.apache.arrow.vector.holders.NullableTimeMilliHolder; @@ -1525,6 +1526,26 @@ public int getIntervalYear(int columnIndex) { return vector.get(rowNumber); } + /** + * Returns a Duration from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getIntervalYear(String columnName, NullableIntervalYearHolder holder) { + IntervalYearVector vector = (IntervalYearVector) table.getVector(columnName); + vector.get(rowNumber, holder); + } + + /** + * Returns an ArrowBuf from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * is thrown if it is present but has a different type + */ + public void getIntervalYear(int columnIndex, NullableIntervalYearHolder holder) { + IntervalYearVector vector = (IntervalYearVector) table.getVector(columnIndex); + vector.get(rowNumber, holder); + } + /** * Updates the value of the holder with data from vector at the given index at the current row. An * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index 115f9aba705..2603d2ede8b 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -49,6 +49,7 @@ import java.nio.charset.StandardCharsets; import java.time.Duration; import java.time.LocalDateTime; +import java.time.Period; import java.util.ArrayList; import java.util.List; @@ -60,6 +61,9 @@ import org.apache.arrow.vector.DurationVector; import org.apache.arrow.vector.FieldVector; import org.apache.arrow.vector.IntervalDayVector; +import org.apache.arrow.vector.IntervalMonthDayNanoVector; +import org.apache.arrow.vector.IntervalYearVector; +import org.apache.arrow.vector.PeriodDuration; import org.apache.arrow.vector.VectorSchemaRoot; import org.apache.arrow.vector.complex.DenseUnionVector; import org.apache.arrow.vector.complex.ListVector; @@ -74,6 +78,8 @@ import org.apache.arrow.vector.holders.NullableFloat8Holder; import org.apache.arrow.vector.holders.NullableIntHolder; import org.apache.arrow.vector.holders.NullableIntervalDayHolder; +import org.apache.arrow.vector.holders.NullableIntervalMonthDayNanoHolder; +import org.apache.arrow.vector.holders.NullableIntervalYearHolder; import org.apache.arrow.vector.holders.NullableSmallIntHolder; import org.apache.arrow.vector.holders.NullableTimeMicroHolder; import org.apache.arrow.vector.holders.NullableTimeMilliHolder; @@ -254,6 +260,80 @@ void getIntervalDay() { } } + @Test + void getIntervalMonth() { + List vectors = new ArrayList<>(); + IntervalUnit unit = IntervalUnit.MONTH_DAY_NANO; + final FieldType fieldType = FieldType.nullable(new ArrowType.Interval(unit)); + + IntervalMonthDayNanoVector intervalMonthVector = new IntervalMonthDayNanoVector("intervalMonth_vector", fieldType, allocator); + NullableIntervalMonthDayNanoHolder holder1 = new NullableIntervalMonthDayNanoHolder(); + NullableIntervalMonthDayNanoHolder holder2 = new NullableIntervalMonthDayNanoHolder(); + + holder1.days = 1; + holder1.months = 10; + holder1.isSet = 1; + holder2.days = 2; + holder2.months = 20; + holder2.isSet = 1; + + vectors.add(intervalMonthVector); + intervalMonthVector.setSafe(0, holder1); + intervalMonthVector.setSafe(1, holder2); + intervalMonthVector.setValueCount(2); + + PeriodDuration one = intervalMonthVector.getObject(1); + try (Table t = new Table(vectors)) { + Row c = t.immutableRow(); + c.setPosition(1); + assertEquals(one, c.getIntervalMonthDayNanoObj("intervalMonth_vector")); + assertEquals(one, c.getIntervalMonthDayNanoObj(0)); + c.getIntervalMonthDayNano(0, holder1); + c.getIntervalMonthDayNano("intervalMonth_vector", holder2); + assertEquals(holder1.days, holder2.days); + assertEquals(holder1.months, holder2.months); + ArrowBuf intMonthBuf1 = c.getIntervalMonthDayNano(0); + ArrowBuf intMonthBuf2 = c.getIntervalMonthDayNano("intervalMonth_vector"); + assertEquals(intMonthBuf1.memoryAddress(), intMonthBuf2.memoryAddress()); + } + } + + @Test + void getIntervalYear() { + List vectors = new ArrayList<>(); + IntervalUnit unit = IntervalUnit.YEAR_MONTH; + final FieldType fieldType = FieldType.nullable(new ArrowType.Interval(unit)); + + IntervalYearVector intervalYearVector = new IntervalYearVector("intervalYear_vector", fieldType, allocator); + NullableIntervalYearHolder holder1 = new NullableIntervalYearHolder(); + NullableIntervalYearHolder holder2 = new NullableIntervalYearHolder(); + + holder1.value = 1; + holder1.isSet = 1; + holder2.value = 2; + holder2.isSet = 1; + + vectors.add(intervalYearVector); + intervalYearVector.setSafe(0, holder1); + intervalYearVector.setSafe(1, holder2); + intervalYearVector.setValueCount(2); + + Period one = intervalYearVector.getObject(1); + try (Table t = new Table(vectors)) { + Row c = t.immutableRow(); + c.setPosition(1); + assertEquals(one, c.getIntervalYearObj("intervalYear_vector")); + assertEquals(one, c.getIntervalYearObj(0)); + c.getIntervalYear(0, holder1); + c.getIntervalYear("intervalYear_vector", holder2); + assertEquals(holder1.value, holder2.value); + int intYear1 = c.getIntervalYear(0); + int intYear2 = c.getIntervalYear("intervalYear_vector"); + assertEquals(2, intYear1); + assertEquals(intYear1, intYear2); + } + } + @Test void getBit() { List vectors = new ArrayList<>(); From 07088bb6f2496d7a8ec8bed797a75fada1702252 Mon Sep 17 00:00:00 2001 From: Larry White Date: Mon, 3 Oct 2022 16:11:04 -0400 Subject: [PATCH 24/40] added missing tests for complex types --- .../org/apache/arrow/vector/table/RowTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index 2603d2ede8b..985620f3c4e 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -707,9 +707,16 @@ void testSimpleStructVector1() { @SuppressWarnings("unchecked") JsonStringHashMap struct = (JsonStringHashMap) c.getStruct(STRUCT_VECTOR_NAME); + @SuppressWarnings("unchecked") + JsonStringHashMap struct1 = + (JsonStringHashMap) c.getStruct(0); int a = (int) struct.get("struct_int_child"); double b = (double) struct.get("struct_flt_child"); + int a1 = (int) struct1.get("struct_int_child"); + double b1 = (double) struct1.get("struct_flt_child"); assertNotNull(struct); + assertEquals(a, a1); + assertEquals(b, b1); assertTrue(a >= 0); assertTrue(b <= a, String.format("a = %s and b = %s", a, b)); } @@ -724,6 +731,8 @@ void testSimpleUnionVector() { Row c = table.immutableRow(); c.setPosition(0); Object object0 = c.getUnion(UNION_VECTOR_NAME); + Object object1 = c.getUnion(0); + assertEquals(object0, object1); c.setPosition(1); assertNull(c.getUnion(UNION_VECTOR_NAME)); c.setPosition(2); @@ -741,6 +750,8 @@ void testSimpleDenseUnionVector() { Row c = table.immutableRow(); c.setPosition(0); Object object0 = c.getDenseUnion(UNION_VECTOR_NAME); + Object object1 = c.getDenseUnion(0); + assertEquals(object0, object1); c.setPosition(1); assertNull(c.getDenseUnion(UNION_VECTOR_NAME)); c.setPosition(2); @@ -760,6 +771,12 @@ void testSimpleMapVector1() { @SuppressWarnings("unchecked") List> list = (List>) c.getMap(BIGINT_INT_MAP_VECTOR_NAME); + @SuppressWarnings("unchecked") + List> list1 = + (List>) c.getMap(0); + for (int j = 0; j < list1.size(); j++) { + assertEquals(list.get(j), list1.get(j)); + } if (list != null && !list.isEmpty()) { assertEquals(i, list.size()); for (JsonStringHashMap sv : list) { From fdaf4a866064c9086a89d0ea6f37d61eabee2062 Mon Sep 17 00:00:00 2001 From: Larry White Date: Mon, 3 Oct 2022 16:42:00 -0400 Subject: [PATCH 25/40] Added tests for extension type, and fixed bug in extensiontype code --- .../org/apache/arrow/vector/table/Row.java | 5 +++-- .../apache/arrow/vector/table/RowTest.java | 22 +++++++++++++++++++ .../vector/types/pojo/TestExtensionType.java | 2 +- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java index a75ef3b92c4..33dc400bcb3 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java @@ -31,6 +31,7 @@ import org.apache.arrow.vector.DecimalVector; import org.apache.arrow.vector.DurationVector; import org.apache.arrow.vector.ExtensionTypeVector; +import org.apache.arrow.vector.FieldVector; import org.apache.arrow.vector.FixedSizeBinaryVector; import org.apache.arrow.vector.Float4Vector; import org.apache.arrow.vector.Float8Vector; @@ -168,7 +169,7 @@ public boolean isNull(int columnIndex) { * IllegalArgumentException is thrown if the type is incorrect. */ public Object getExtensionType(int vectorIndex) { - ExtensionTypeVector vector = (ExtensionTypeVector) table.getVector(vectorIndex); + FieldVector vector = table.getVector(vectorIndex); return vector.getObject(rowNumber); } @@ -181,7 +182,7 @@ public Object getExtensionType(int vectorIndex) { * @return The object in the named column at the current row */ public Object getExtensionType(String columnName) { - ExtensionTypeVector vector = (ExtensionTypeVector) table.getVector(columnName); + FieldVector vector = table.getVector(columnName); return vector.getObject(rowNumber); } diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index 985620f3c4e..afddf61d717 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -102,6 +102,7 @@ import org.apache.arrow.vector.types.TimeUnit; import org.apache.arrow.vector.types.pojo.ArrowType; import org.apache.arrow.vector.types.pojo.FieldType; +import org.apache.arrow.vector.types.pojo.TestExtensionType; import org.apache.arrow.vector.util.JsonStringHashMap; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -761,6 +762,27 @@ void testSimpleDenseUnionVector() { } } + @Test + void testExtensionTypeVector() { + TestExtensionType.LocationVector vector = new TestExtensionType.LocationVector("location", allocator); + vector.allocateNew(); + vector.set(0, 34.073814f, -118.240784f); + vector.setValueCount(1); + + try (VectorSchemaRoot vsr = VectorSchemaRoot.of(vector); + Table table = new Table(vsr)) { + Row c = table.immutableRow(); + c.setPosition(0); + Object object0 = c.getExtensionType("location"); + Object object1 = c.getExtensionType(0); + assertEquals(object0, object1); + @SuppressWarnings("unchecked") + JsonStringHashMap struct0 = + (JsonStringHashMap) object0; + assertEquals(34.073814f, struct0.get("Latitude")); + } + } + @Test void testSimpleMapVector1() { try (MapVector mapVector = simpleMapVector(allocator); diff --git a/java/vector/src/test/java/org/apache/arrow/vector/types/pojo/TestExtensionType.java b/java/vector/src/test/java/org/apache/arrow/vector/types/pojo/TestExtensionType.java index 8b2743210de..1b3d5eee35f 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/types/pojo/TestExtensionType.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/types/pojo/TestExtensionType.java @@ -380,7 +380,7 @@ public FieldVector getNewVector(String name, FieldType fieldType, BufferAllocato } } - static class LocationVector extends ExtensionTypeVector { + public static class LocationVector extends ExtensionTypeVector { private static StructVector buildUnderlyingVector(String name, BufferAllocator allocator) { final StructVector underlyingVector = From 38451d29f2a42b81c287bbd1ae748f1374c5e620 Mon Sep 17 00:00:00 2001 From: Larry White Date: Mon, 3 Oct 2022 16:43:47 -0400 Subject: [PATCH 26/40] remove unnecessary import statement --- java/vector/src/main/java/org/apache/arrow/vector/table/Row.java | 1 - 1 file changed, 1 deletion(-) diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java index 33dc400bcb3..0d8822902df 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java @@ -30,7 +30,6 @@ import org.apache.arrow.vector.BitVector; import org.apache.arrow.vector.DecimalVector; import org.apache.arrow.vector.DurationVector; -import org.apache.arrow.vector.ExtensionTypeVector; import org.apache.arrow.vector.FieldVector; import org.apache.arrow.vector.FixedSizeBinaryVector; import org.apache.arrow.vector.Float4Vector; From 420b7eb3526488c0cf3b057f5b982180ad6948b2 Mon Sep 17 00:00:00 2001 From: Larry White Date: Mon, 3 Oct 2022 16:48:38 -0400 Subject: [PATCH 27/40] cleanup --- .../main/java/org/apache/arrow/vector/table/BaseTable.java | 6 ------ .../src/main/java/org/apache/arrow/vector/table/Row.java | 6 ------ 2 files changed, 12 deletions(-) diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java index 3964fa6dad6..1059120268d 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java @@ -244,8 +244,6 @@ public VectorSchemaRoot toVectorSchemaRoot() { * Returns the vector with the given name, or {@code null} if the name is not found. Names are * case-sensitive. * - *

    TODO: Consider whether we could avoid doing a linear search of the entries - * * @param columnName The name of the vector * @return the Vector with the given name, or null */ @@ -278,8 +276,6 @@ public Row immutableRow() { /** * Returns a tab separated value of vectors (based on their java object representation). - * - * TODO: Consider moving to a separate object so code can be shared with VSR */ public String contentToTSVString() { StringBuilder sb = new StringBuilder(); @@ -322,8 +318,6 @@ private void printRow(StringBuilder sb, List row) { * *

    If the index is larger than the number of rows, the method returns true. * - * TODO: Consider renaming to a test that includes the notion of within the valid range - * * @param rowNumber The 0-based index of the possibly deleted row * @return true if the row at the index was deleted; false otherwise */ diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java index 0d8822902df..5988b863600 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java @@ -1713,12 +1713,6 @@ public String getLargeVarChar(int columnIndex) { return new String(vector.get(rowNumber), getDefaultCharacterSet()); } - // TODO: Implement getters for - // List & LargeList - // plus (for dealing with nulls?) - // all the object getters for things like TimeStampTz for Boxed return results (e.g. long v Long) - // plus ones using holders - /** * Returns true if there is at least one more non-deleted row in the table that has yet to be * processed. From 2259219ebd5f8808fd779ad454a552a90a66535e Mon Sep 17 00:00:00 2001 From: Larry White Date: Mon, 3 Oct 2022 16:53:24 -0400 Subject: [PATCH 28/40] fix line length --- .../src/test/java/org/apache/arrow/vector/table/RowTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index afddf61d717..eb841259855 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -267,7 +267,8 @@ void getIntervalMonth() { IntervalUnit unit = IntervalUnit.MONTH_DAY_NANO; final FieldType fieldType = FieldType.nullable(new ArrowType.Interval(unit)); - IntervalMonthDayNanoVector intervalMonthVector = new IntervalMonthDayNanoVector("intervalMonth_vector", fieldType, allocator); + IntervalMonthDayNanoVector intervalMonthVector = + new IntervalMonthDayNanoVector("intervalMonth_vector", fieldType, allocator); NullableIntervalMonthDayNanoHolder holder1 = new NullableIntervalMonthDayNanoHolder(); NullableIntervalMonthDayNanoHolder holder2 = new NullableIntervalMonthDayNanoHolder(); From 26de767d59f3b7ef877f017d03378259efac5cd8 Mon Sep 17 00:00:00 2001 From: Larry White Date: Mon, 3 Oct 2022 20:09:53 -0400 Subject: [PATCH 29/40] Documentation and minor cleanup --- .../apache/arrow/vector/table/BaseTable.java | 5 +- .../org/apache/arrow/vector/table/Row.java | 472 +++++++++--------- .../apache/arrow/vector/table/RowTest.java | 23 + 3 files changed, 264 insertions(+), 236 deletions(-) diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java index 1059120268d..b405782c777 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseTable.java @@ -241,11 +241,12 @@ public VectorSchemaRoot toVectorSchemaRoot() { } /** - * Returns the vector with the given name, or {@code null} if the name is not found. Names are + * Returns the vector with the given name, or throws IllegalArgumentException if the name is not found. Names are * case-sensitive. * * @param columnName The name of the vector * @return the Vector with the given name, or null + * @throws IllegalArgumentException if the name is not the name of a vector in the table. */ FieldVector getVector(String columnName) { for (Map.Entry entry : fieldVectorsMap.entrySet()) { @@ -253,7 +254,7 @@ FieldVector getVector(String columnName) { return entry.getValue(); } } - return null; + throw new IllegalStateException(String.format("No vector named '%s' is present in the table", columnName)); } /** diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java index 5988b863600..c7d6e8c1428 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java @@ -96,8 +96,7 @@ import org.apache.arrow.vector.holders.NullableUInt8Holder; /** - * Row is a positionable, immutable cursor backed by a {@link Table}. If a row in a table is - * marked as deleted, it is skipped when iterating. + * Row is a positionable, immutable cursor backed by a {@link Table}. * *

    Getters are provided for most vector types. The exceptions being {@link org.apache.arrow.vector.NullVector}, * which only contains null values and has no getter, and {@link org.apache.arrow.vector.ZeroVector}, @@ -156,16 +155,21 @@ public boolean isNull(String columnName) { return vector.isNull(rowNumber); } - /** Returns true if the value at columnName is null, and false otherwise. */ + /** + * For vectors other than Union and DenseUnion, returns true if the value at columnIndex is null, + * and false otherwise. + * + *

    UnionVector#isNull always returns false, but the underlying vector may hold null values. + */ public boolean isNull(int columnIndex) { ValueVector vector = table.getVector(columnIndex); return vector.isNull(rowNumber); } /** - * Returns an object representing the value in the named ExtensionTypeVector at the currentRow. An + * Returns an object representing the value in the ExtensionTypeVector at the currentRow and vectorIndex. An * IllegalStateException is thrown if the column is not present in the Row and an - * IllegalArgumentException is thrown if the type is incorrect. + * ClassCastException is thrown if the type is incorrect. */ public Object getExtensionType(int vectorIndex) { FieldVector vector = table.getVector(vectorIndex); @@ -173,9 +177,9 @@ public Object getExtensionType(int vectorIndex) { } /** - * Returns an object representing the value in the ExtensionTypeVector at the currentRow. An + * Returns an object representing the value in the named ExtensionTypeVector at the currentRow. An * IllegalStateException is thrown if the column is not present in the Row and an - * IllegalArgumentException is thrown if it has a different type. + * ClassCastException is thrown if it has a different type. * * @param columnName The name of the vector providing the result * @return The object in the named column at the current row @@ -186,8 +190,8 @@ public Object getExtensionType(String columnName) { } /** - * Returns a Map from the column of the given name at the current row. An IllegalStateException is - * thrown if the column is not present in the Row and an IllegalArgumentException is thrown if + * Returns a Map from the column of the given vectorIndex at the current row. An IllegalStateException is + * thrown if the column is not present in the Row and a ClassCastException is thrown if * it has a different type. */ public List getMap(int vectorIndex) { @@ -197,7 +201,7 @@ public List getMap(int vectorIndex) { /** * Returns a Map from the column of the given name at the current row. An IllegalStateException is - * thrown if the column is not present in the Row and an IllegalArgumentException is thrown if + * thrown if the column is not present in the Row and a ClassCastException is thrown if * it has a different type */ public List getMap(String columnName) { @@ -206,9 +210,9 @@ public List getMap(String columnName) { } /** - * Returns an Object from the column of the given name at the current row. An + * Returns an Object from the column at vectorIndex at the current row. An * IllegalStateException is thrown if the column is not present in the Row and an - * IllegalArgumentException is thrown if it has a different type + * ClassCastException is thrown if it has a different type */ public Object getStruct(int vectorIndex) { StructVector vector = (StructVector) table.getVector(vectorIndex); @@ -218,7 +222,7 @@ public Object getStruct(int vectorIndex) { /** * Returns an Object from the column of the given name at the current row. An * IllegalStateException is thrown if the column is not present in the Row and an - * IllegalArgumentException is thrown if it has a different type + * ClassCastException is thrown if it has a different type */ public Object getStruct(String columnName) { StructVector vector = (StructVector) table.getVector(columnName); @@ -226,9 +230,9 @@ public Object getStruct(String columnName) { } /** - * Returns a List from the column with the given index at the current row. An + * Returns an Object from the column with the given index at the current row. An * IllegalStateException is thrown if the column is not present in the Row and an - * IllegalArgumentException is thrown if it has a different type + * ClassCastException is thrown if it has a different type */ public Object getUnion(int vectorIndex) { UnionVector vector = (UnionVector) table.getVector(vectorIndex); @@ -236,9 +240,9 @@ public Object getUnion(int vectorIndex) { } /** - * Returns an object from the column of the given name at the current row. An + * Returns an Object from the column of the given name at the current row. An * IllegalStateException is thrown if the column is not present in the Row and an - * IllegalArgumentException is thrown if it has a different type + * ClassCastException is thrown if it has a different type */ public Object getUnion(String columnName) { UnionVector vector = (UnionVector) table.getVector(columnName); @@ -246,9 +250,9 @@ public Object getUnion(String columnName) { } /** - * Returns an object from the column of the given name at the current row. An + * Returns an Object from the column of the given name at the current row. An * IllegalStateException is thrown if the column is not present in the Row and an - * IllegalArgumentException is thrown if it has a different type + * ClassCastException is thrown if it has a different type */ public Object getDenseUnion(String columnName) { DenseUnionVector vector = (DenseUnionVector) table.getVector(columnName); @@ -256,9 +260,9 @@ public Object getDenseUnion(String columnName) { } /** - * Returns a List from the column with the given index at the current row. An + * Returns an Object from the column with the given vectorIndex at the current row. An * IllegalStateException is thrown if the column is not present in the Row and an - * IllegalArgumentException is thrown if it has a different type + * ClassCastException is thrown if it has a different type */ public Object getDenseUnion(int vectorIndex) { DenseUnionVector vector = (DenseUnionVector) table.getVector(vectorIndex); @@ -267,7 +271,7 @@ public Object getDenseUnion(int vectorIndex) { /** * Returns a List from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present in the Row and an IllegalArgumentException is thrown + * is thrown if the column is not present in the Row and a ClassCastException is thrown * if it has a different type */ public List getList(String columnName) { @@ -277,7 +281,7 @@ public List getList(String columnName) { /** * Returns a List from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present and an IllegalArgumentException is + * IllegalStateException is thrown if the column is not present and a ClassCastException is * thrown if it has a different type */ public List getList(int columnIndex) { @@ -287,7 +291,7 @@ public List getList(int columnIndex) { /** * Returns an int from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present in the Row and an IllegalArgumentException is thrown + * is thrown if the column is not present in the Row and a ClassCastException is thrown * if it has a different type */ public int getInt(String columnName) { @@ -297,7 +301,7 @@ public int getInt(String columnName) { /** * Returns an int from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present and an IllegalArgumentException is + * IllegalStateException is thrown if the column is not present and a ClassCastException is * thrown if it has a different type */ public int getInt(int columnIndex) { @@ -306,9 +310,9 @@ public int getInt(int columnIndex) { } /** - * Updates the holder with the value at the column of the given name at the current row. An + * Updates the holder with the value in the column of the given name at the current row. An * IllegalStateException is thrown if the column is not present in the Row and an - * IllegalArgumentException is thrown if it has a different type + * ClassCastException is thrown if it has a different type */ public void getInt(String columnName, NullableIntHolder holder) { IntVector vector = (IntVector) table.getVector(columnName); @@ -316,8 +320,8 @@ public void getInt(String columnName, NullableIntHolder holder) { } /** - * Updates the holder with the value at the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present and an IllegalArgumentException is + * Updates the holder with the value in the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present and a ClassCastException is * thrown if it has a different type */ public void getInt(int columnIndex, NullableIntHolder holder) { @@ -327,7 +331,7 @@ public void getInt(int columnIndex, NullableIntHolder holder) { /** * Returns an int from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present in the Row and an IllegalArgumentException is thrown + * is thrown if the column is not present in the Row and a ClassCastException is thrown * if it has a different type */ public int getUInt4(String columnName) { @@ -337,7 +341,7 @@ public int getUInt4(String columnName) { /** * Returns an int from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present and an IllegalArgumentException is + * IllegalStateException is thrown if the column is not present and a ClassCastException is * thrown if it has a different type */ public int getUInt4(int columnIndex) { @@ -348,7 +352,7 @@ public int getUInt4(int columnIndex) { /** * Updates the holder with the value at the column of the given name at the current row. An * IllegalStateException is thrown if the column is not present in the Row and an - * IllegalArgumentException is thrown if it has a different type + * ClassCastException is thrown if it has a different type */ public void getUInt4(String columnName, NullableUInt4Holder holder) { UInt4Vector vector = (UInt4Vector) table.getVector(columnName); @@ -357,7 +361,7 @@ public void getUInt4(String columnName, NullableUInt4Holder holder) { /** * Updates the holder with the value at the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present and an IllegalArgumentException is + * IllegalStateException is thrown if the column is not present and a ClassCastException is * thrown if it has a different type */ public void getUInt4(int columnIndex, NullableUInt4Holder holder) { @@ -367,7 +371,7 @@ public void getUInt4(int columnIndex, NullableUInt4Holder holder) { /** * Returns a short from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public short getSmallInt(String columnName) { @@ -377,7 +381,7 @@ public short getSmallInt(String columnName) { /** * Returns a short from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public short getSmallInt(int columnIndex) { @@ -386,8 +390,8 @@ public short getSmallInt(int columnIndex) { } /** - * Updates the holder with the value at the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value in the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getSmallInt(String columnName, NullableSmallIntHolder holder) { @@ -396,8 +400,8 @@ public void getSmallInt(String columnName, NullableSmallIntHolder holder) { } /** - * Updates the holder with the value at the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value in the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getSmallInt(int columnIndex, NullableSmallIntHolder holder) { @@ -407,7 +411,7 @@ public void getSmallInt(int columnIndex, NullableSmallIntHolder holder) { /** * Returns a char from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public char getUInt2(String columnName) { @@ -417,7 +421,7 @@ public char getUInt2(String columnName) { /** * Returns a char from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public char getUInt2(int columnIndex) { @@ -426,8 +430,8 @@ public char getUInt2(int columnIndex) { } /** - * Updates the holder with the value at the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value in the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getUInt2(String columnName, NullableUInt2Holder holder) { @@ -436,8 +440,8 @@ public void getUInt2(String columnName, NullableUInt2Holder holder) { } /** - * Updates the holder with the value at the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value in the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getUInt2(int columnIndex, NullableUInt2Holder holder) { @@ -447,7 +451,7 @@ public void getUInt2(int columnIndex, NullableUInt2Holder holder) { /** * Returns a byte from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public byte getTinyInt(String columnName) { @@ -457,7 +461,7 @@ public byte getTinyInt(String columnName) { /** * Returns a byte from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public byte getTinyInt(int columnIndex) { @@ -466,8 +470,8 @@ public byte getTinyInt(int columnIndex) { } /** - * Updates the holder with the value at the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value in the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getTinyInt(String columnName, NullableTinyIntHolder holder) { @@ -476,8 +480,8 @@ public void getTinyInt(String columnName, NullableTinyIntHolder holder) { } /** - * Updates the holder with the value at the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value in the column at the given index and current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getTinyInt(int columnIndex, NullableTinyIntHolder holder) { @@ -487,7 +491,7 @@ public void getTinyInt(int columnIndex, NullableTinyIntHolder holder) { /** * Returns a byte from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public byte getUInt1(String columnName) { @@ -497,7 +501,7 @@ public byte getUInt1(String columnName) { /** * Returns a byte from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public byte getUInt1(int columnIndex) { @@ -506,8 +510,8 @@ public byte getUInt1(int columnIndex) { } /** - * Updates the holder with the value at the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value in the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getUInt1(String columnName, NullableUInt1Holder holder) { @@ -516,8 +520,8 @@ public void getUInt1(String columnName, NullableUInt1Holder holder) { } /** - * Updates the holder with the value at the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value in the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getUInt1(int columnIndex, NullableUInt1Holder holder) { @@ -527,7 +531,7 @@ public void getUInt1(int columnIndex, NullableUInt1Holder holder) { /** * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public long getBigInt(String columnName) { @@ -537,7 +541,7 @@ public long getBigInt(String columnName) { /** * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public long getBigInt(int columnIndex) { @@ -546,8 +550,8 @@ public long getBigInt(int columnIndex) { } /** - * Updates the holder with the value at the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value in the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getBigInt(String columnName, NullableBigIntHolder holder) { @@ -556,8 +560,8 @@ public void getBigInt(String columnName, NullableBigIntHolder holder) { } /** - * Updates the holder with the value at the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value in the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getBigInt(int columnIndex, NullableBigIntHolder holder) { @@ -567,7 +571,7 @@ public void getBigInt(int columnIndex, NullableBigIntHolder holder) { /** * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public long getUInt8(String columnName) { @@ -577,7 +581,7 @@ public long getUInt8(String columnName) { /** * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public long getUInt8(int columnIndex) { @@ -586,8 +590,8 @@ public long getUInt8(int columnIndex) { } /** - * Updates the holder with the value at the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value in the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getUInt8(String columnName, NullableUInt8Holder holder) { @@ -596,8 +600,8 @@ public void getUInt8(String columnName, NullableUInt8Holder holder) { } /** - * Updates the holder with the value at the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value in the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getUInt8(int columnIndex, NullableUInt8Holder holder) { @@ -607,7 +611,7 @@ public void getUInt8(int columnIndex, NullableUInt8Holder holder) { /** * Returns a float from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public float getFloat4(String columnName) { @@ -616,8 +620,8 @@ public float getFloat4(String columnName) { } /** - * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Returns a float from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public float getFloat4(int columnIndex) { @@ -626,8 +630,8 @@ public float getFloat4(int columnIndex) { } /** - * Updates the holder with the value at the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value in the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getFloat4(String columnName, NullableFloat4Holder holder) { @@ -636,8 +640,8 @@ public void getFloat4(String columnName, NullableFloat4Holder holder) { } /** - * Updates the holder with the value at the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value in the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getFloat4(int columnIndex, NullableFloat4Holder holder) { @@ -647,7 +651,7 @@ public void getFloat4(int columnIndex, NullableFloat4Holder holder) { /** * Returns a double from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public double getFloat8(String columnName) { @@ -657,7 +661,7 @@ public double getFloat8(String columnName) { /** * Returns a double from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public double getFloat8(int columnIndex) { @@ -666,9 +670,9 @@ public double getFloat8(int columnIndex) { } /** - * Returns a double from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is - * present but has a different type + * Updates the holder with the value in the column with the given index at the current row. + * An IllegalStateException is thrown if the column is not present, and a ClassCastException is thrown + * if it is present but has a different type */ public void getFloat8(String columnName, NullableFloat8Holder holder) { Float8Vector vector = (Float8Vector) table.getVector(columnName); @@ -676,8 +680,8 @@ public void getFloat8(String columnName, NullableFloat8Holder holder) { } /** - * Updates the holder with the value at the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value in the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getFloat8(int columnIndex, NullableFloat8Holder holder) { @@ -686,8 +690,8 @@ public void getFloat8(int columnIndex, NullableFloat8Holder holder) { } /** - * Updates the holder with the value at the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Returns an int from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public int getBit(String columnName) { @@ -697,7 +701,7 @@ public int getBit(String columnName) { /** * Returns an int from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public int getBit(int columnIndex) { @@ -706,8 +710,8 @@ public int getBit(int columnIndex) { } /** - * Updates the holder with the value at the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value in the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getBit(String columnName, NullableBitHolder holder) { @@ -716,8 +720,8 @@ public void getBit(String columnName, NullableBitHolder holder) { } /** - * Updates the holder with the value at the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value in the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getBit(int columnIndex, NullableBitHolder holder) { @@ -727,7 +731,7 @@ public void getBit(int columnIndex, NullableBitHolder holder) { /** * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public long getTimeNano(String columnName) { @@ -737,7 +741,7 @@ public long getTimeNano(String columnName) { /** * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public long getTimeNano(int columnIndex) { @@ -746,9 +750,9 @@ public long getTimeNano(int columnIndex) { } /** - * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is - * present but has a different type + * Updates the holder with the value in the column with the given name at the current row. + * An IllegalStateException is thrown if the column is not present, and a ClassCastException is thrown + * if it is present but has a different type */ public void getTimeNano(String columnName, NullableTimeNanoHolder holder) { TimeNanoVector vector = (TimeNanoVector) table.getVector(columnName); @@ -756,8 +760,8 @@ public void getTimeNano(String columnName, NullableTimeNanoHolder holder) { } /** - * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value in the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type. */ public void getTimeNano(int columnIndex, NullableTimeNanoHolder holder) { @@ -767,7 +771,7 @@ public void getTimeNano(int columnIndex, NullableTimeNanoHolder holder) { /** * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type. */ public long getTimeMicro(String columnName) { @@ -777,7 +781,7 @@ public long getTimeMicro(String columnName) { /** * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type. */ public long getTimeMicro(int columnIndex) { @@ -786,8 +790,8 @@ public long getTimeMicro(int columnIndex) { } /** - * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * Updates the holder with the value from the column of the given name at the current row. + * An IllegalStateException is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type. */ public void getTimeMicro(String columnName, NullableTimeMicroHolder holder) { @@ -796,8 +800,8 @@ public void getTimeMicro(String columnName, NullableTimeMicroHolder holder) { } /** - * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type. */ public void getTimeMicro(int columnIndex, NullableTimeMicroHolder holder) { @@ -807,7 +811,7 @@ public void getTimeMicro(int columnIndex, NullableTimeMicroHolder holder) { /** * Returns an int from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type. */ public int getTimeMilli(String columnName) { @@ -817,7 +821,7 @@ public int getTimeMilli(String columnName) { /** * Returns an int from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type. */ public int getTimeMilli(int columnIndex) { @@ -826,8 +830,8 @@ public int getTimeMilli(int columnIndex) { } /** - * Returns an int from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * Updates the holder with the value from the column of the given name at the current row. + * An IllegalStateException is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type. */ public void getTimeMilli(String columnName, NullableTimeMilliHolder holder) { @@ -836,8 +840,8 @@ public void getTimeMilli(String columnName, NullableTimeMilliHolder holder) { } /** - * Returns an int from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type. */ public void getTimeMilli(int columnIndex, NullableTimeMilliHolder holder) { @@ -846,8 +850,8 @@ public void getTimeMilli(int columnIndex, NullableTimeMilliHolder holder) { } /** - * Returns an int from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * Returns a LocalDateTime from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type. */ public LocalDateTime getTimeMilliObj(String columnName) { @@ -856,8 +860,8 @@ public LocalDateTime getTimeMilliObj(String columnName) { } /** - * Returns an int from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Returns a LocalDateTime from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type. */ public LocalDateTime getTimeMilliObj(int columnIndex) { @@ -867,7 +871,7 @@ public LocalDateTime getTimeMilliObj(int columnIndex) { /** * Returns an int from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type. */ public int getTimeSec(String columnName) { @@ -877,7 +881,7 @@ public int getTimeSec(String columnName) { /** * Returns an int from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type. */ public int getTimeSec(int columnIndex) { @@ -886,8 +890,8 @@ public int getTimeSec(int columnIndex) { } /** - * Returns an int from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * Updates the holder with the value from the column of the given name at the current row. + * An IllegalStateException is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type. */ public void getTimeSec(String columnName, NullableTimeSecHolder holder) { @@ -896,8 +900,8 @@ public void getTimeSec(String columnName, NullableTimeSecHolder holder) { } /** - * Returns an int from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type. */ public void getTimeSec(int columnIndex, NullableTimeSecHolder holder) { @@ -907,7 +911,7 @@ public void getTimeSec(int columnIndex, NullableTimeSecHolder holder) { /** * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type. */ public long getTimeStampSec(String columnName) { @@ -917,7 +921,7 @@ public long getTimeStampSec(String columnName) { /** * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public long getTimeStampSec(int columnIndex) { @@ -926,8 +930,8 @@ public long getTimeStampSec(int columnIndex) { } /** - * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * Updates the holder with the value from the column of the given name at the current row. + * An IllegalStateException is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public void getTimeStampSec(String columnName, NullableTimeStampSecHolder holder) { @@ -936,8 +940,8 @@ public void getTimeStampSec(String columnName, NullableTimeStampSecHolder holder } /** - * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getTimeStampSec(int columnIndex, NullableTimeStampSecHolder holder) { @@ -946,8 +950,8 @@ public void getTimeStampSec(int columnIndex, NullableTimeStampSecHolder holder) } /** - * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * Returns a LocalDateTime from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public LocalDateTime getTimeStampSecObj(String columnName) { @@ -956,8 +960,8 @@ public LocalDateTime getTimeStampSecObj(String columnName) { } /** - * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Returns a LocalDateTime from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public LocalDateTime getTimeStampSecObj(int columnIndex) { @@ -966,8 +970,8 @@ public LocalDateTime getTimeStampSecObj(int columnIndex) { } /** - * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * Updates the holder with the value from the column of the given name at the current row. + * An IllegalStateException is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public long getTimeStampSecTZ(String columnName) { @@ -977,7 +981,7 @@ public long getTimeStampSecTZ(String columnName) { /** * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public long getTimeStampSecTZ(int columnIndex) { @@ -986,8 +990,8 @@ public long getTimeStampSecTZ(int columnIndex) { } /** - * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * Updates the holder with the value from the column of the given name at the current row. + * An IllegalStateException is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public void getTimeStampSecTZ(String columnName, NullableTimeStampSecTZHolder holder) { @@ -996,8 +1000,8 @@ public void getTimeStampSecTZ(String columnName, NullableTimeStampSecTZHolder ho } /** - * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value from the column with the given index at the current row. + * An IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getTimeStampSecTZ(int columnIndex, NullableTimeStampSecTZHolder holder) { @@ -1007,7 +1011,7 @@ public void getTimeStampSecTZ(int columnIndex, NullableTimeStampSecTZHolder hold /** * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public long getTimeStampNano(String columnName) { @@ -1017,7 +1021,7 @@ public long getTimeStampNano(String columnName) { /** * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public long getTimeStampNano(int columnIndex) { @@ -1026,8 +1030,8 @@ public long getTimeStampNano(int columnIndex) { } /** - * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * Updates the holder with the value from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public void getTimeStampNano(String columnName, NullableTimeStampNanoHolder holder) { @@ -1036,8 +1040,8 @@ public void getTimeStampNano(String columnName, NullableTimeStampNanoHolder hold } /** - * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getTimeStampNano(int columnIndex, NullableTimeStampNanoHolder holder) { @@ -1047,7 +1051,7 @@ public void getTimeStampNano(int columnIndex, NullableTimeStampNanoHolder holder /** * Returns a LocalDateTime from the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public LocalDateTime getTimeStampNanoObj(String columnName) { @@ -1057,7 +1061,7 @@ public LocalDateTime getTimeStampNanoObj(String columnName) { /** * Returns a LocalDateTime from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public LocalDateTime getTimeStampNanoObj(int columnIndex) { @@ -1067,7 +1071,7 @@ public LocalDateTime getTimeStampNanoObj(int columnIndex) { /** * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public long getTimeStampNanoTZ(String columnName) { @@ -1077,7 +1081,7 @@ public long getTimeStampNanoTZ(String columnName) { /** * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public long getTimeStampNanoTZ(int columnIndex) { @@ -1086,8 +1090,8 @@ public long getTimeStampNanoTZ(int columnIndex) { } /** - * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * Updates the holder with the value from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public void getTimeStampNanoTZ(String columnName, NullableTimeStampNanoTZHolder holder) { @@ -1096,8 +1100,8 @@ public void getTimeStampNanoTZ(String columnName, NullableTimeStampNanoTZHolder } /** - * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getTimeStampNanoTZ(int columnIndex, NullableTimeStampNanoTZHolder holder) { @@ -1107,7 +1111,7 @@ public void getTimeStampNanoTZ(int columnIndex, NullableTimeStampNanoTZHolder ho /** * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public long getTimeStampMilli(String columnName) { @@ -1117,7 +1121,7 @@ public long getTimeStampMilli(String columnName) { /** * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public long getTimeStampMilli(int columnIndex) { @@ -1126,8 +1130,8 @@ public long getTimeStampMilli(int columnIndex) { } /** - * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * Updates the holder with the value from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public void getTimeStampMilli(String columnName, NullableTimeStampMilliHolder holder) { @@ -1136,8 +1140,8 @@ public void getTimeStampMilli(String columnName, NullableTimeStampMilliHolder ho } /** - * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getTimeStampMilli(int columnIndex, NullableTimeStampMilliHolder holder) { @@ -1147,7 +1151,7 @@ public void getTimeStampMilli(int columnIndex, NullableTimeStampMilliHolder hold /** * Returns a LocalDateTime from the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public LocalDateTime getTimeStampMilliObj(String columnName) { @@ -1157,7 +1161,7 @@ public LocalDateTime getTimeStampMilliObj(String columnName) { /** * Returns a LocalDateTime from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public LocalDateTime getTimeStampMilliObj(int columnIndex) { @@ -1167,7 +1171,7 @@ public LocalDateTime getTimeStampMilliObj(int columnIndex) { /** * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public long getTimeStampMilliTZ(String columnName) { @@ -1177,7 +1181,7 @@ public long getTimeStampMilliTZ(String columnName) { /** * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public long getTimeStampMilliTZ(int columnIndex) { @@ -1186,8 +1190,8 @@ public long getTimeStampMilliTZ(int columnIndex) { } /** - * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * Updates the holder with the value from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different types */ public void getTimeStampMilliTZ(String columnName, NullableTimeStampMilliTZHolder holder) { @@ -1196,8 +1200,8 @@ public void getTimeStampMilliTZ(String columnName, NullableTimeStampMilliTZHolde } /** - * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getTimeStampMilliTZ(int columnIndex, NullableTimeStampMilliTZHolder holder) { @@ -1207,7 +1211,7 @@ public void getTimeStampMilliTZ(int columnIndex, NullableTimeStampMilliTZHolder /** * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public long getTimeStampMicro(String columnName) { @@ -1217,7 +1221,7 @@ public long getTimeStampMicro(String columnName) { /** * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public long getTimeStampMicro(int columnIndex) { @@ -1226,8 +1230,8 @@ public long getTimeStampMicro(int columnIndex) { } /** - * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * Updates the holder with the value from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public void getTimeStampMicro(String columnName, NullableTimeStampMicroHolder holder) { @@ -1236,8 +1240,8 @@ public void getTimeStampMicro(String columnName, NullableTimeStampMicroHolder ho } /** - * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getTimeStampMicro(int columnIndex, NullableTimeStampMicroHolder holder) { @@ -1247,7 +1251,7 @@ public void getTimeStampMicro(int columnIndex, NullableTimeStampMicroHolder hold /** * Returns a LocalDateTime from the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public LocalDateTime getTimeStampMicroObj(String columnName) { @@ -1257,7 +1261,7 @@ public LocalDateTime getTimeStampMicroObj(String columnName) { /** * Returns a LocalDateTime from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public LocalDateTime getTimeStampMicroObj(int columnIndex) { @@ -1267,7 +1271,7 @@ public LocalDateTime getTimeStampMicroObj(int columnIndex) { /** * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public long getTimeStampMicroTZ(String columnName) { @@ -1277,7 +1281,7 @@ public long getTimeStampMicroTZ(String columnName) { /** * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public long getTimeStampMicroTZ(int columnIndex) { @@ -1286,8 +1290,8 @@ public long getTimeStampMicroTZ(int columnIndex) { } /** - * Returns a long from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * Updates the holder with the value from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public void getTimeStampMicroTZ(String columnName, NullableTimeStampMicroTZHolder holder) { @@ -1296,8 +1300,8 @@ public void getTimeStampMicroTZ(String columnName, NullableTimeStampMicroTZHolde } /** - * Returns a long from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getTimeStampMicroTZ(int columnIndex, NullableTimeStampMicroTZHolder holder) { @@ -1307,7 +1311,7 @@ public void getTimeStampMicroTZ(int columnIndex, NullableTimeStampMicroTZHolder /** * Returns a Duration from the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public Duration getDurationObj(String columnName) { @@ -1317,7 +1321,7 @@ public Duration getDurationObj(String columnName) { /** * Returns a Duration from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public Duration getDurationObj(int columnIndex) { @@ -1327,7 +1331,7 @@ public Duration getDurationObj(int columnIndex) { /** * Returns an ArrowBuf from the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public ArrowBuf getDuration(String columnName) { @@ -1337,7 +1341,7 @@ public ArrowBuf getDuration(String columnName) { /** * Returns an ArrowBuf from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public ArrowBuf getDuration(int columnIndex) { @@ -1346,8 +1350,8 @@ public ArrowBuf getDuration(int columnIndex) { } /** - * Returns a Duration from the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getDuration(String columnName, NullableDurationHolder holder) { @@ -1356,8 +1360,8 @@ public void getDuration(String columnName, NullableDurationHolder holder) { } /** - * Returns a Duration from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getDuration(int columnIndex, NullableDurationHolder holder) { @@ -1367,7 +1371,7 @@ public void getDuration(int columnIndex, NullableDurationHolder holder) { /** * Returns a PeriodDuration from the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public PeriodDuration getIntervalMonthDayNanoObj(String columnName) { @@ -1377,7 +1381,7 @@ public PeriodDuration getIntervalMonthDayNanoObj(String columnName) { /** * Returns a PeriodDuration from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public PeriodDuration getIntervalMonthDayNanoObj(int columnIndex) { @@ -1386,8 +1390,8 @@ public PeriodDuration getIntervalMonthDayNanoObj(int columnIndex) { } /** - * Returns a PeriodDuration from the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Returns an ArrowBuf from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public ArrowBuf getIntervalMonthDayNano(String columnName) { @@ -1396,8 +1400,8 @@ public ArrowBuf getIntervalMonthDayNano(String columnName) { } /** - * Returns a PeriodDuration from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Returns an ArrowBuf from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public ArrowBuf getIntervalMonthDayNano(int columnIndex) { @@ -1406,8 +1410,8 @@ public ArrowBuf getIntervalMonthDayNano(int columnIndex) { } /** - * Returns a PeriodDuration from the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getIntervalMonthDayNano( @@ -1417,8 +1421,8 @@ public void getIntervalMonthDayNano( } /** - * Returns a PeriodDuration from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getIntervalMonthDayNano(int columnIndex, NullableIntervalMonthDayNanoHolder holder) { @@ -1427,8 +1431,8 @@ public void getIntervalMonthDayNano(int columnIndex, NullableIntervalMonthDayNan } /** - * Returns a Duration from the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Returns an ArrowBuf from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public ArrowBuf getIntervalDay(String columnName) { @@ -1438,7 +1442,7 @@ public ArrowBuf getIntervalDay(String columnName) { /** * Returns an ArrowBuf from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public ArrowBuf getIntervalDay(int columnIndex) { @@ -1447,8 +1451,8 @@ public ArrowBuf getIntervalDay(int columnIndex) { } /** - * Returns a Duration from the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getIntervalDay(String columnName, NullableIntervalDayHolder holder) { @@ -1457,8 +1461,8 @@ public void getIntervalDay(String columnName, NullableIntervalDayHolder holder) } /** - * Returns an ArrowBuf from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getIntervalDay(int columnIndex, NullableIntervalDayHolder holder) { @@ -1468,7 +1472,7 @@ public void getIntervalDay(int columnIndex, NullableIntervalDayHolder holder) { /** * Returns a Duration from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public Duration getIntervalDayObj(int columnIndex) { @@ -1478,7 +1482,7 @@ public Duration getIntervalDayObj(int columnIndex) { /** * Returns a Duration from the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public Duration getIntervalDayObj(String columnName) { @@ -1488,7 +1492,7 @@ public Duration getIntervalDayObj(String columnName) { /** * Returns a Period from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public Period getIntervalYearObj(String columnName) { @@ -1498,7 +1502,7 @@ public Period getIntervalYearObj(String columnName) { /** * Returns a Period from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public Period getIntervalYearObj(int columnIndex) { @@ -1507,8 +1511,8 @@ public Period getIntervalYearObj(int columnIndex) { } /** - * Returns a Period from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * Returns an int from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public int getIntervalYear(String columnName) { @@ -1517,8 +1521,8 @@ public int getIntervalYear(String columnName) { } /** - * Returns a Period from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Returns an int from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public int getIntervalYear(int columnIndex) { @@ -1527,8 +1531,8 @@ public int getIntervalYear(int columnIndex) { } /** - * Returns a Duration from the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getIntervalYear(String columnName, NullableIntervalYearHolder holder) { @@ -1537,8 +1541,8 @@ public void getIntervalYear(String columnName, NullableIntervalYearHolder holder } /** - * Returns an ArrowBuf from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Updates the holder with the value from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getIntervalYear(int columnIndex, NullableIntervalYearHolder holder) { @@ -1548,7 +1552,7 @@ public void getIntervalYear(int columnIndex, NullableIntervalYearHolder holder) /** * Updates the value of the holder with data from vector at the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getDecimal(int columnIndex, NullableDecimalHolder holder) { @@ -1558,7 +1562,7 @@ public void getDecimal(int columnIndex, NullableDecimalHolder holder) { /** * Updates the value of the holder with data from the vector with given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public void getDecimal(String columnName, NullableDecimalHolder holder) { @@ -1568,7 +1572,7 @@ public void getDecimal(String columnName, NullableDecimalHolder holder) { /** * Returns a BigDecimal from the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public BigDecimal getDecimalObj(String columnName) { @@ -1578,7 +1582,7 @@ public BigDecimal getDecimalObj(String columnName) { /** * Returns a BigDecimal from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public BigDecimal getDecimalObj(int columnIndex) { @@ -1587,8 +1591,8 @@ public BigDecimal getDecimalObj(int columnIndex) { } /** - * Returns a BigDecimal from the column of the given name at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Returns an ArrowBuf from the column of the given name at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public ArrowBuf getDecimal(String columnName) { @@ -1597,8 +1601,8 @@ public ArrowBuf getDecimal(String columnName) { } /** - * Returns a BigDecimal from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * Returns an ArrowBuf from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public ArrowBuf getDecimal(int columnIndex) { @@ -1608,7 +1612,7 @@ public ArrowBuf getDecimal(int columnIndex) { /** * Returns a byte[] from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public byte[] getVarBinary(String columnName) { @@ -1618,7 +1622,7 @@ public byte[] getVarBinary(String columnName) { /** * Returns a byte[] from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public byte[] getVarBinary(int columnIndex) { @@ -1628,7 +1632,7 @@ public byte[] getVarBinary(int columnIndex) { /** * Returns a byte[] from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public byte[] getFixedSizeBinary(String columnName) { @@ -1638,7 +1642,7 @@ public byte[] getFixedSizeBinary(String columnName) { /** * Returns a byte[] from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public byte[] getFixedSizeBinary(int columnIndex) { @@ -1648,7 +1652,7 @@ public byte[] getFixedSizeBinary(int columnIndex) { /** * Returns a byte[] from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present, and an IllegalArgumentException is thrown if it is + * is thrown if the column is not present, and a ClassCastException is thrown if it is * present but has a different type */ public byte[] getLargeVarBinary(String columnName) { @@ -1658,7 +1662,7 @@ public byte[] getLargeVarBinary(String columnName) { /** * Returns a byte[] from the column with the given index at the current row. An - * IllegalStateException is thrown if the column is not present, and an IllegalArgumentException + * IllegalStateException is thrown if the column is not present, and a ClassCastException * is thrown if it is present but has a different type */ public byte[] getLargeVarBinary(int columnIndex) { @@ -1668,7 +1672,7 @@ public byte[] getLargeVarBinary(int columnIndex) { /** * Returns a String from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present in the Row and an IllegalArgumentException is thrown + * is thrown if the column is not present in the Row and a ClassCastException is thrown * if it has a different type * *

    StandardCharsets.UTF_8 is used as the charset @@ -1681,7 +1685,7 @@ public String getVarChar(String columnName) { /** * Returns a String from the column with the given index at the current row. An * IllegalStateException is thrown if the column is not present in the Row and an - * IllegalArgumentException is thrown if it has a different type + * ClassCastException is thrown if it has a different type * * @param columnIndex the index of the FieldVector holding the value */ @@ -1692,7 +1696,7 @@ public String getVarChar(int columnIndex) { /** * Returns a String from the column of the given name at the current row. An IllegalStateException - * is thrown if the column is not present in the Row and an IllegalArgumentException is thrown + * is thrown if the column is not present in the Row and a ClassCastException is thrown * if it has a different type * *

    StandardCharsets.UTF_8 is used as the charset, unless this cursor was created with a default @@ -1706,7 +1710,7 @@ public String getLargeVarChar(String columnName) { /** * Returns a String from the column with the given index at the current row. An * IllegalStateException is thrown if the column is not present in the Row and an - * IllegalArgumentException is thrown if it has a different type + * ClassCastException is thrown if it has a different type */ public String getLargeVarChar(int columnIndex) { LargeVarCharVector vector = (LargeVarCharVector) table.getVector(columnIndex); @@ -1753,7 +1757,7 @@ private boolean setNextObject() { } /** - * Returns new internal iterator that processes every row, deleted or not. Users should use the + * Returns new internal iterator that processes every row, deleted or not. Use the * wrapping next() and hasNext() methods rather than using this iterator directly, unless you want * to see any deleted rows. */ diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index eb841259855..f59fe73a8ce 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -43,6 +43,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import java.math.BigDecimal; @@ -162,6 +163,28 @@ void getIntByVectorName() { } } + @Test + void testNameNotFound() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + Row c = t.immutableRow(); + c.setPosition(1); + assertThrows(IllegalStateException.class, + ()-> c.getVarChar("wrong name")); + } + } + + @Test + void testWrongType() { + List vectorList = twoIntColumns(allocator); + try (Table t = new Table(vectorList)) { + Row c = t.immutableRow(); + c.setPosition(1); + assertThrows(ClassCastException.class, + ()-> c.getVarChar(INT_VECTOR_NAME_1)); + } + } + @Test void getDecimal() { List vectors = new ArrayList<>(); From a92fff96c00a982b9967ddb114d22ddf4c733cf2 Mon Sep 17 00:00:00 2001 From: Larry White Date: Mon, 3 Oct 2022 20:10:44 -0400 Subject: [PATCH 30/40] fix whitespace --- .../src/test/java/org/apache/arrow/vector/table/RowTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index f59fe73a8ce..43db0725417 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -170,7 +170,7 @@ void testNameNotFound() { Row c = t.immutableRow(); c.setPosition(1); assertThrows(IllegalStateException.class, - ()-> c.getVarChar("wrong name")); + () -> c.getVarChar("wrong name")); } } @@ -181,7 +181,7 @@ void testWrongType() { Row c = t.immutableRow(); c.setPosition(1); assertThrows(ClassCastException.class, - ()-> c.getVarChar(INT_VECTOR_NAME_1)); + () -> c.getVarChar(INT_VECTOR_NAME_1)); } } From 0159c8f15e8b93b43f14c5c50d5ab1a6bc7ac900 Mon Sep 17 00:00:00 2001 From: Larry White Date: Mon, 3 Oct 2022 20:13:54 -0400 Subject: [PATCH 31/40] Update BaseTableTest.java --- .../java/org/apache/arrow/vector/table/BaseTableTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java index 3cf8668ac10..6f31d96aa61 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java @@ -26,6 +26,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.ArrayList; @@ -175,7 +176,8 @@ void testGetVector() { List vectorList = twoIntColumns(allocator); try (Table t = new Table(vectorList)) { assertNotNull(t.getVector(INT_VECTOR_NAME_1)); - assertNull(t.getVector("foobar")); + assertThrows(IllegalStateException.class, + () -> t.getVector("wrong name")); } } From 27a9bb6755f4672fe56711d8a729c6d7ffe7374c Mon Sep 17 00:00:00 2001 From: Larry White Date: Mon, 3 Oct 2022 20:40:21 -0400 Subject: [PATCH 32/40] remove unused import --- .../test/java/org/apache/arrow/vector/table/BaseTableTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java index 6f31d96aa61..6812785e72b 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/BaseTableTest.java @@ -25,7 +25,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; From 20339dca1efae46d9c7fa6f93e4f1c938cbe1913 Mon Sep 17 00:00:00 2001 From: Larry White Date: Tue, 4 Oct 2022 09:08:19 -0400 Subject: [PATCH 33/40] Added Table test to RoundTripTest --- .../org/apache/arrow/c/RoundtripTest.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/java/c/src/test/java/org/apache/arrow/c/RoundtripTest.java b/java/c/src/test/java/org/apache/arrow/c/RoundtripTest.java index fb7714fac0b..61f26768acd 100644 --- a/java/c/src/test/java/org/apache/arrow/c/RoundtripTest.java +++ b/java/c/src/test/java/org/apache/arrow/c/RoundtripTest.java @@ -90,6 +90,7 @@ import org.apache.arrow.vector.holders.IntervalDayHolder; import org.apache.arrow.vector.holders.NullableLargeVarBinaryHolder; import org.apache.arrow.vector.holders.NullableUInt4Holder; +import org.apache.arrow.vector.table.Table; import org.apache.arrow.vector.types.TimeUnit; import org.apache.arrow.vector.types.Types.MinorType; import org.apache.arrow.vector.types.pojo.ArrowType; @@ -657,6 +658,39 @@ public void testVectorSchemaRoot() { imported.close(); } + /** + * Tests exporting Table and importing back to VSR. Importing back to Table is not supported at present. + */ + @Test + public void testTable() { + VectorSchemaRoot imported; + + // Consumer allocates empty structures + try (ArrowSchema consumerArrowSchema = ArrowSchema.allocateNew(allocator); + ArrowArray consumerArrowArray = ArrowArray.allocateNew(allocator)) { + try ( + VectorSchemaRoot vsr = createTestVSR(); + Table table = new Table(vsr); + ) { + // Producer creates structures from existing memory pointers + try (ArrowSchema arrowSchema = ArrowSchema.wrap(consumerArrowSchema.memoryAddress()); + ArrowArray arrowArray = ArrowArray.wrap(consumerArrowArray.memoryAddress())) { + // Producer exports vector into the C Data Interface structures + Data.exportTable(allocator, table, arrowArray); + } + } + // Consumer imports vector + imported = Data.importVectorSchemaRoot(allocator, consumerArrowArray, consumerArrowSchema, null); + } + + // Ensure that imported VectorSchemaRoot is valid even after C Data Interface + // structures are closed + try (VectorSchemaRoot original = createTestVSR()) { + assertTrue(imported.equals(original)); + } + imported.close(); + } + @Test public void testVectorSchemaRootWithDuplicatedFieldNames() { VectorSchemaRoot imported; From 5efff416e70495e1cf5c20d35fe203f18ebe785b Mon Sep 17 00:00:00 2001 From: Larry White Date: Tue, 4 Oct 2022 10:48:09 -0400 Subject: [PATCH 34/40] Update README.md --- .../org/apache/arrow/vector/table/README.md | 210 ++++++++++-------- 1 file changed, 116 insertions(+), 94 deletions(-) diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md index 9e99bedf755..16ed41ff290 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md @@ -1,10 +1,8 @@ # Table -**NOTE**: The API is experimental and subject to change. +**NOTE**: The API is experimental and subject to change. See the list of limitations below. -**NOTE**: Major limitations in this release are listed at the end of the document. - -*Table* is a new immutable tabular data structure based on FieldVectors. A mutable version (*MutableTable*) is expected in a subsequent release. This document describes the Table API. +*Table* is a new immutable tabular data structure based on FieldVectors. A mutable version (*MutableTable*) is expected in a subsequent release. This document describes the Table API. --- @@ -12,7 +10,7 @@ Like VectorSchemaRoot, *Table* is a columnar data structure backed by Arrow arra ## Mutation in Table and VectorSchemaRoot -VectorSchemaRoot provides a thin wrapper on the FieldVectors that hold its data. Individual FieldVectors can be retrieved from the VectorSchemaRoot. These FieldVectors have *setters* for modifying their elements, so VectorSchemaRoot is immutable only by convention. The protocol for mutating a vector is documented in the ValueVector class: +VectorSchemaRoot provides a thin wrapper on the FieldVectors that hold its data. Individual FieldVectors can be retrieved from the VectorSchemaRoot. These FieldVectors have *setters* for modifying their elements, so VectorSchemaRoot is immutable only by convention. The protocol for mutating a vector is documented in the ValueVector class: - values need to be written in order (e.g. index 0, 1, 2, 5) - null vectors start with all values as null before writing anything @@ -20,10 +18,36 @@ VectorSchemaRoot provides a thin wrapper on the FieldVectors that hold its data. - you must call setValueCount before a vector can be read - you should never write to a vector once it has been read. -The rules aren't enforced by the API so the programmer is responsible for ensuring that they are followed. Failure to do so could lead to runtime exceptions. +The rules aren't enforced by the API so the programmer is responsible for ensuring that they are followed. Failure to do so could lead to runtime exceptions. _Table_, on the other hand, is immutable. The underlying vectors are not exposed. When a Table is created from existing vectors, their memory is transferred to new vectors, so subsequent changes to the original vectors can't impact the new table's values. +## Features and limitations + +### Features +A basic set of table functionality is included in this release: + +- Create a Table from FieldVectors or VectorSchemaRoot +- Iterate tables by row or set the current row index directly +- Access Vector values as primitives, objects, and/or NullableHolders (depending on type) +- Get FieldReader for any vector +- Add and remove FieldVectors +- Encode and decode a table's vectors using DictionaryEncoding +- Export Table memory for use by native code +- Print first rows to Strings +- Get table schema +- Slice tables +- Convert table to VectorSchemaRoot + +### Limitations +The following are the major limitations of v. 10.0.0 release: + +1. **Creating Tables with data imported using the C-Data API will result in a runtime exception**. Support for ths feature is gated on PR#13248 (https://github.com/apache/arrow/pull/13248). +2. No support ChunkedArrays or any form of row-group. Support for ChunkedArrows or row groups will be considered for a future release. +3. No support for native interface using the C-Stream API. Support for the streaming API will be delivered with or after Item 1. +4. No support for creating tables directly from Java POJOs. All data held by a table must be imported via a VectorSchemaRoot, or from collections or arrays of FieldVectors. +5. No support for mutable tables. + ## What's in a Table? Like VectorSchemaRoot, Table consists of a `Schema` and an ordered collection of `FieldVector` objects, but it is designed to be accessed via a row-oriented interface. @@ -32,87 +56,87 @@ Like VectorSchemaRoot, Table consists of a `Schema` and an ordered collection of ### Creating a Table from a VectorSchemaRoot -Tables are created from a VectorSchemaRoot as shown below. The memory buffers holding the data are transferred from the VectorSchemaRoot to new vectors in the new Table, clearing the original VectorSchemaRoot in the process. This ensures that the data in your new Table is never changed. Since the buffers are transferred rather than copied, this is a very low overhead operation. +Tables are created from a VectorSchemaRoot as shown below. The memory buffers holding the data are transferred from the VectorSchemaRoot to new vectors in the new Table, clearing the original VectorSchemaRoot in the process. This ensures that the data in your new Table is never changed. Since the buffers are transferred rather than copied, this is a very low overhead operation. ```java -VectorSchemaRoot vsr = getMyVsr(); -Table t = new Table(vsr); +VectorSchemaRoot vsr = getMyVsr(); + Table t = new Table(vsr); ``` -If you now update the FieldVectors used to create the VectorSchemaRoot (using some variation of `ValueVector#setSafe()`), the VectorSchemaRoot *vsr* would reflect those changes, but the values in Table *t* are unchanged. +If you now update the FieldVectors used to create the VectorSchemaRoot (using some variation of `ValueVector#setSafe()`), the VectorSchemaRoot *vsr* would reflect those changes, but the values in Table *t* are unchanged. -***Current Limitation:*** Due to an unresolved limitation in `CDataReferenceManager`, you cannot currently create a Table from a VectorSchemaRoot that was created in native code and transferred to Java via the C-Data Interface. +***Current Limitation:*** Due to an unresolved limitation in `CDataReferenceManager`, you cannot currently create a Table from a VectorSchemaRoot that was created in native code and transferred to Java via the C-Data Interface. ### Creating a Table from ValueVectors Tables can be created from ValueVectors as shown below. ```java -IntVector myVector = createMyIntVector(); -VectorSchemaRoot vsr1 = new VectorSchemaRoot(myVector); +IntVector myVector = createMyIntVector(); + VectorSchemaRoot vsr1 = new VectorSchemaRoot(myVector); ``` -or +or ```java -IntVector myVector = createMyIntVector(); -List fvList = List.of(myVector); -VectorSchemaRoot vsr1 = new VectorSchemaRoot(fvList); +IntVector myVector = createMyIntVector(); + List fvList = List.of(myVector); + VectorSchemaRoot vsr1 = new VectorSchemaRoot(fvList); ``` -It is rarely a good idea to share vectors between multiple VectorSchemaRoots, and it would not be a good idea to share them between VectorSchemaRoots and tables. Creating a VectorSchemaRoot from a list of vectors does not cause the reference counts for the vectors to be incremented. Unless you manage the counts manually, the code shown below would lead to more references to the vectors than reference counts, and that could lead to trouble. There is an implicit assumption that the vectors were created for use by *one* VectorSchemaRoot that this code violates. +It is rarely a good idea to share vectors between multiple VectorSchemaRoots, and it would not be a good idea to share them between VectorSchemaRoots and tables. Creating a VectorSchemaRoot from a list of vectors does not cause the reference counts for the vectors to be incremented. Unless you manage the counts manually, the code shown below would lead to more references to the vectors than reference counts, and that could lead to trouble. There is an implicit assumption that the vectors were created for use by *one* VectorSchemaRoot that this code violates. *Don't do this:* ```Java IntVector myVector = createMyIntVector(); // Reference count for myVector = 1 -VectorSchemaRoot vsr1 = new VectorSchemaRoot(myVector); // Still one reference -VectorSchemaRoot vsr2 = new VectorSchemaRoot(myVector); + VectorSchemaRoot vsr1 = new VectorSchemaRoot(myVector); // Still one reference + VectorSchemaRoot vsr2 = new VectorSchemaRoot(myVector); // Ref count is still one, but there are two VSRs with a reference to myVector -vsr2.clear(); // Reference count for myVector is 0. + vsr2.clear(); // Reference count for myVector is 0. ``` -What is happening is that the reference counter works at a lower level than the VectorSchemaRoot interface. A reference counter counts references to ArrowBuf instances that control memory buffers. It doesn't count references to the ValueVectors that hold *them*. In the example above, each ArrowBuf is held by one ValueVector, so there is only one reference. This distinction is blurred though, when you call the VectorSchemaRoot's clear() method, which frees the memory held by each of the vectors it references even though another instance might refer to the same vectors. +What is happening is that the reference counter works at a lower level than the VectorSchemaRoot interface. A reference counter counts references to ArrowBuf instances that control memory buffers. It doesn't count references to the ValueVectors that hold *them*. In the example above, each ArrowBuf is held by one ValueVector, so there is only one reference. This distinction is blurred though, when you call the VectorSchemaRoot's clear() method, which frees the memory held by each of the vectors it references even though another instance might refer to the same vectors. -When you create Tables from vectors, it's assumed that there are no external references to those vectors. But, just to be on the safe side, the buffers underlying these vectors are transferred to new ValueVectors in the new Table, and the original vectors are cleared. +When you create Tables from vectors, it's assumed that there are no external references to those vectors. But, just to be on the safe side, the buffers underlying these vectors are transferred to new ValueVectors in the new Table, and the original vectors are cleared. *Don't do this either, but note the difference from above:* ```Java IntVector myVector = createMyIntVector(); // Reference count for myVector = 1 -Table t1 = new Table(myVector); // myVector is cleared; Table t1 has a new hidden vector with - // the data from myVector -Table t2 = new Table(myVector); // t2 has no rows because the myVector was just cleared - // t1 continues to have the data from the original vector -t2.clear(); // no change because t2 is already empty and t1 is independent + Table t1 = new Table(myVector); // myVector is cleared; Table t1 has a new hidden vector with + // the data from myVector + Table t2 = new Table(myVector); // t2 has no rows because the myVector was just cleared + // t1 continues to have the data from the original vector + t2.clear(); // no change because t2 is already empty and t1 is independent ``` -With Tables, memory is explicitly transferred on instantiatlon so the buffers are held by that table are held by *only* that table. +With Tables, memory is explicitly transferred on instantiatlon so the buffers are held by that table are held by *only* that table. #### Creating Tables with dictionary-encoded vectors ***Note: this section is highly speculative*** -Another point of difference is that dictionary-encoding is managed separately from VectorSchemaRoot, while Tables hold an optional DictionaryProvider instance. If any vectors in the source data are encoded, a DictionaryProvider must be set to un-encode the values. +Another point of difference is that dictionary-encoding is managed separately from VectorSchemaRoot, while Tables hold an optional DictionaryProvider instance. If any vectors in the source data are encoded, a DictionaryProvider must be set to un-encode the values. ```java -VectorSchemaRoot vsr = myVsr(); -DictionaryProvider provider = myProvider(); -Table t = new Table(vsr, provider); +VectorSchemaRoot vsr = myVsr(); + DictionaryProvider provider = myProvider(); + Table t = new Table(vsr, provider); ``` In the immutable Table case, dictionaries are used in a way that's similar to the approach used with ValueVectors. To decode a vector, the user provides the dictionary id and the name of the vector to decode: ```Java Table t = new Table(vsr, provider); -ValueVector decodedName = t.decode("name", 1L); + ValueVector decodedName = t.decode("name", 1L); ``` To encode a vector from a table, a similar approach is used: ```Java Table t = new Table(vsr, provider); -ValueVector encodedName = t.encode("name", 1L); + ValueVector encodedName = t.encode("name", 1L); ``` ***Current Limitation:*** One difference is the method that produces TSV formatted output has an extra switch instructing the Table to replace the encoded output with the decoded output where possible: @@ -123,26 +147,26 @@ String output = myTable.contentToTSVString(true); ### Freeing memory explicitly -Tables use off-heap memory that must be freed when it is no longer needed. Table implements AutoCloseable so the best way to create one is in a try-with-resources block: +Tables use off-heap memory that must be freed when it is no longer needed. Table implements AutoCloseable so the best way to create one is in a try-with-resources block: ```java -try (VectorSchemaRoot vsr = myMethodForGettingVsrs(); - Table t = new Table(vsr)) { - // do useful things. -} +try (VectorSchemaRoot vsr = myMethodForGettingVsrs(); + Table t = new Table(vsr)) { + // do useful things. + } ``` If you don't use a try-with-resources block, you must close the Table manually: ````java try { - VectorSchemaRoot vsr = myMethodForGettingVsrs(); - Table t = new Table(vsr); - // do useful things. -} finally { - vsr.close(); - t.close(); -} + VectorSchemaRoot vsr = myMethodForGettingVsrs(); + Table t = new Table(vsr); + // do useful things. + } finally { + vsr.close(); + t.close(); + } ```` Manually closing should be performed in a finally block. @@ -161,36 +185,36 @@ Table provides facilities for adding and removing FieldVectors modeled on the sa ```java try (Table t = new Table(vectorList)) { - IntVector v3 = new IntVector("3", intFieldType, allocator); - Table t2 = t.addVector(2, v3); - Table t3 = t2.removeVector(1); - // don't forget to close t2 and t3 -} + IntVector v3 = new IntVector("3", intFieldType, allocator); + Table t2 = t.addVector(2, v3); + Table t3 = t2.removeVector(1); + // don't forget to close t2 and t3 + } ``` ## Table API: Slicing tables -Table supports *slice()* operations, where a slice of a source table is a second Table that refers to a single, contiguous range of rows in the source. +Table supports *slice()* operations, where a slice of a source table is a second Table that refers to a single, contiguous range of rows in the source. ```Java try (Table t = new Table(vectorList)) { - Table t2 = t.slice(100, 200); // creates a slice referencing the values in range (100, 200] - ... -} + Table t2 = t.slice(100, 200); // creates a slice referencing the values in range (100, 200] + ... + } ``` If you created a slice with *all* the values in the source table (as shown below), how would that differ from a new Table constructed with the same vectors as the source? ```Java try (Table t = new Table(vectorList)) { - Table t2 = t.slice(0, t.getRowCount()); // creates a slice referencing all the values in t - // ... -} + Table t2 = t.slice(0, t.getRowCount()); // creates a slice referencing all the values in t + // ... + } ``` -The difference is that when you *construct* a new table, the buffers are transferred from the source vectors to new vectors in the destination. With a slice, both tables share the same underlying vectors. That's OK, though, since both Tables are immutable. +The difference is that when you *construct* a new table, the buffers are transferred from the source vectors to new vectors in the destination. With a slice, both tables share the same underlying vectors. That's OK, though, since both Tables are immutable. -Slices will not be supported in MutableTables. +Slices will not be supported in MutableTables. ## Table API: Using FieldReaders @@ -219,73 +243,73 @@ Row r = table.immutableRow(); Since rows are iterable, you can traverse a table using a standard while loop: ```java -Row r = table.immutableRow(); -while (c.hasNext()) { - c.next(); - // do something useful here -} +Row r = table.immutableRow(); + while (c.hasNext()) { + c.next(); + // do something useful here + } ``` Table implements `Iterable` so you can access rows directly from Table in an enhanced *for* loop: ```java for (Row row: table) { - int age = row.getInt("age"); - boolean nameIsNull = row.isNull("name"); - ... -} + int age = row.getInt("age"); + boolean nameIsNull = row.isNull("name"); + ... + } ``` -Finally, while rows are usually iterated in the order of the underlying data vectors, but they are also positionable using the `Row#setPosition()` method, so you can skip to a specific row. Row numbers are 0-based. +Finally, while rows are usually iterated in the order of the underlying data vectors, but they are also positionable using the `Row#setPosition()` method, so you can skip to a specific row. Row numbers are 0-based. ```java -Row r = table.immutableRow(); -int age101 = c.setPosition(101); // change position directly to 101 +Row r = table.immutableRow(); + int age101 = c.setPosition(101); // change position directly to 101 ``` -Any changes to position are of course applied to all the columns in the table. +Any changes to position are of course applied to all the columns in the table. -Note that you must call `next()`, or `setPosition()` before accessing values via a row. Failure to do so results in a runtime exception. +Note that you must call `next()`, or `setPosition()` before accessing values via a row. Failure to do so results in a runtime exception. ### Read operations using rows Methods are available for getting values by vector name and vector index, where index is the 0-based position of the vector in the table. For example, assuming 'age' is the 13th vector in 'table', the following two gets are equivalent: ```java -Row r = table.immutableRow(); -c.next(); // position the row at the first value -int age1 = c.get("age"); // gets the value of vector named 'age' in the table at row 0 -int age2 = c.get(12); // gets the value of the 13th vecto in the table at row 0 +Row r = table.immutableRow(); + c.next(); // position the row at the first value + int age1 = c.get("age"); // gets the value of vector named 'age' in the table at row 0 + int age2 = c.get(12); // gets the value of the 13th vecto in the table at row 0 ``` -You can also get value using a NullableHolder. For example: +You can also get value using a NullableHolder. For example: ```Java -NullableIntHolder holder = new NullableIntHolder(); -int b = row.getInt("age", holder); +NullableIntHolder holder = new NullableIntHolder(); + int b = row.getInt("age", holder); ``` -This can be used to retrieve values without creating a new Object for each. +This can be used to retrieve values without creating a new Object for each. -In addition to getting values, you can check if a value is null using `isNull()` and you can get the current row number: +In addition to getting values, you can check if a value is null using `isNull()` and you can get the current row number: ```java boolean name0isNull = row.isNull("name"); -int row = row.getRowNumber(); + int row = row.getRowNumber(); ``` Note that while there are getters for most vector types (e.g. *getInt()* for use with IntVector) and a generic *isNull()* method, there is no *getNull()* method for use with the NullVector type or *getZero()* for use with ZeroVector (a zero-length vector of any type). #### Reading values as Objects -For any given vector type, the basic *get()* method returns a primitive value wherever possible. For example, *getTimeStampMicro()* returns a long value that encodes the timestamp. To get the LocalDateTime object representing that timestamp in Java, another method with 'Obj' appended to the name is provided. For example: +For any given vector type, the basic *get()* method returns a primitive value wherever possible. For example, *getTimeStampMicro()* returns a long value that encodes the timestamp. To get the LocalDateTime object representing that timestamp in Java, another method with 'Obj' appended to the name is provided. For example: ```java long ts = row.getTimeStampMicro(); -LocalDateTime tsObject = row.getTimeStampMicroObj(); + LocalDateTime tsObject = row.getTimeStampMicroObj(); ``` -The exception to this naming scheme is for complex vector types (List, Map, Schema, Union, DenseUnion, and ExtensionType). These always return objects rather than primitives so no "Obj" extension is required. It is expected that some users may subclass Row to add getters that are more specific to their needs. +The exception to this naming scheme is for complex vector types (List, Map, Schema, Union, DenseUnion, and ExtensionType). These always return objects rather than primitives so no "Obj" extension is required. It is expected that some users may subclass Row to add getters that are more specific to their needs. #### Reading VarChars and LargeVarChars @@ -297,7 +321,7 @@ String v1 = row.getVarChar("first_name"); // uses the default encoding (UT ## Table API: Converting a Table to a VectorSchemaRoot -Tables can be converted to VectorSchemaRoot objects using the *toVectorSchemaRoot()* method. +Tables can be converted to VectorSchemaRoot objects using the *toVectorSchemaRoot()* method. ```java VectorSchemaRoot root = myTable.toVectorSchemaRoot(); @@ -325,18 +349,16 @@ Data.exportTable(bufferAllocator, table, outArrowArray); ### Importing Tables from native code -***Current limitation: Data imported from native code using the C-Data-interface cannot be used in a table, because the current implementation of CDataReferenceManager does not support the transfer operation.*** +***Current limitation: Data imported from native code using the C-Data-interface cannot be used in a table, because the current implementation of CDataReferenceManager does not support the transfer operation.*** ## Table API: Working with the C-Stream interface ***Current limitation: Streaming API is not currently supported. Support is planned for a future release.*** -## Implementation notes - The following are the major limitations of v. 10.0.0 release: 1. No support ChunkedArrays or any form of row-group. Support for ChunkedArrows or row groups will be considered for a future release. -2. No support for native interface using the C-Stream API. Support for the streaming API will be delivered with or after Item 1. +2. No support for native interface using the C-Stream API. Support for the streaming API will be delivered with or after Item 1. 3. No ability to use Tables with data imported from native code using the C-Data API. Support for ths feature is gated on PR#13248 (https://github.com/apache/arrow/pull/13248). 4. No support for creating tables directly from Java POJOs. All data held by a table must be imported via a VectorSchemaRoot, or from collections or arrays of FieldVectors. -5. No support for mutable tables. \ No newline at end of file +5. No support for mutable tables. From a68d114f6a55998276fd69fba4f47a4fccfe9db5 Mon Sep 17 00:00:00 2001 From: Larry White Date: Tue, 4 Oct 2022 11:14:25 -0400 Subject: [PATCH 35/40] fixed inconsistent method signature --- .../org/apache/arrow/vector/table/README.md | 5 +- .../org/apache/arrow/vector/table/Row.java | 55 +++++++++++++++++-- .../apache/arrow/vector/table/RowTest.java | 16 ++++-- 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md index 16ed41ff290..a0a0c6bf0cf 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md @@ -313,10 +313,11 @@ The exception to this naming scheme is for complex vector types (List, Map, Sche #### Reading VarChars and LargeVarChars -Strings in arrow are represented as byte arrays, encoded with the UTF-8 charset as this is the only character set supported in the Arrow format. +Strings in arrow are represented as byte arrays, encoded with the UTF-8 charset as this is the only character set supported in the Arrow format. You can get either a String result or the actual byte array. ```Java -String v1 = row.getVarChar("first_name"); // uses the default encoding (UTF-8) +byte[] b = row.getVarChar("first_name"); +String s = row.getVarCharObj("first_name"); // uses the default encoding (UTF-8) ``` ## Table API: Converting a Table to a VectorSchemaRoot diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java index c7d6e8c1428..e09ef219f98 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java @@ -1677,7 +1677,7 @@ public byte[] getLargeVarBinary(int columnIndex) { * *

    StandardCharsets.UTF_8 is used as the charset */ - public String getVarChar(String columnName) { + public String getVarCharObj(String columnName) { VarCharVector vector = (VarCharVector) table.getVector(columnName); return new String(vector.get(rowNumber), getDefaultCharacterSet()); } @@ -1689,11 +1689,35 @@ public String getVarChar(String columnName) { * * @param columnIndex the index of the FieldVector holding the value */ - public String getVarChar(int columnIndex) { + public String getVarCharObj(int columnIndex) { VarCharVector vector = (VarCharVector) table.getVector(columnIndex); return new String(vector.get(rowNumber), getDefaultCharacterSet()); } + /** + * Returns a byte[] from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present in the Row and a ClassCastException is thrown + * if it has a different type + * + *

    StandardCharsets.UTF_8 is used as the charset + */ + public byte[] getVarChar(String columnName) { + VarCharVector vector = (VarCharVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a byte[] from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present in the Row and an + * ClassCastException is thrown if it has a different type + * + * @param columnIndex the index of the FieldVector holding the value + */ + public byte[] getVarChar(int columnIndex) { + VarCharVector vector = (VarCharVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + /** * Returns a String from the column of the given name at the current row. An IllegalStateException * is thrown if the column is not present in the Row and a ClassCastException is thrown @@ -1702,7 +1726,7 @@ public String getVarChar(int columnIndex) { *

    StandardCharsets.UTF_8 is used as the charset, unless this cursor was created with a default * Charset */ - public String getLargeVarChar(String columnName) { + public String getLargeVarCharObj(String columnName) { LargeVarCharVector vector = (LargeVarCharVector) table.getVector(columnName); return new String(vector.get(rowNumber), getDefaultCharacterSet()); } @@ -1712,11 +1736,34 @@ public String getLargeVarChar(String columnName) { * IllegalStateException is thrown if the column is not present in the Row and an * ClassCastException is thrown if it has a different type */ - public String getLargeVarChar(int columnIndex) { + public String getLargeVarCharObj(int columnIndex) { LargeVarCharVector vector = (LargeVarCharVector) table.getVector(columnIndex); return new String(vector.get(rowNumber), getDefaultCharacterSet()); } + /** + * Returns a byte[] from the column of the given name at the current row. An IllegalStateException + * is thrown if the column is not present in the Row and a ClassCastException is thrown + * if it has a different type + * + *

    StandardCharsets.UTF_8 is used as the charset, unless this cursor was created with a default + * Charset + */ + public byte[] getLargeVarChar(String columnName) { + LargeVarCharVector vector = (LargeVarCharVector) table.getVector(columnName); + return vector.get(rowNumber); + } + + /** + * Returns a byte[] from the column with the given index at the current row. An + * IllegalStateException is thrown if the column is not present in the Row and an + * ClassCastException is thrown if it has a different type + */ + public byte[] getLargeVarChar(int columnIndex) { + LargeVarCharVector vector = (LargeVarCharVector) table.getVector(columnIndex); + return vector.get(rowNumber); + } + /** * Returns true if there is at least one more non-deleted row in the table that has yet to be * processed. diff --git a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java index 43db0725417..8feaddbeb35 100644 --- a/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java +++ b/java/vector/src/test/java/org/apache/arrow/vector/table/RowTest.java @@ -170,7 +170,7 @@ void testNameNotFound() { Row c = t.immutableRow(); c.setPosition(1); assertThrows(IllegalStateException.class, - () -> c.getVarChar("wrong name")); + () -> c.getVarCharObj("wrong name")); } } @@ -181,7 +181,7 @@ void testWrongType() { Row c = t.immutableRow(); c.setPosition(1); assertThrows(ClassCastException.class, - () -> c.getVarChar(INT_VECTOR_NAME_1)); + () -> c.getVarCharObj(INT_VECTOR_NAME_1)); } } @@ -648,8 +648,10 @@ void getVarChar() { try (Table t = new Table(vectorList)) { Row c = t.immutableRow(); c.setPosition(1); - assertEquals(c.getVarChar(1), "two"); - assertEquals(c.getVarChar(1), c.getVarChar(VARCHAR_VECTOR_NAME_1)); + assertEquals(c.getVarCharObj(1), "two"); + assertEquals(c.getVarCharObj(1), c.getVarCharObj(VARCHAR_VECTOR_NAME_1)); + assertArrayEquals("two".getBytes(), c.getVarChar(VARCHAR_VECTOR_NAME_1)); + assertArrayEquals("two".getBytes(), c.getVarChar(1)); } } @@ -681,8 +683,10 @@ void getLargeVarChar() { try (Table t = new Table(vectorList)) { Row c = t.immutableRow(); c.setPosition(1); - assertEquals(c.getLargeVarChar(1), "two"); - assertEquals(c.getLargeVarChar(1), c.getLargeVarChar(VARCHAR_VECTOR_NAME_1)); + assertEquals(c.getLargeVarCharObj(1), "two"); + assertEquals(c.getLargeVarCharObj(1), c.getLargeVarCharObj(VARCHAR_VECTOR_NAME_1)); + assertArrayEquals("two".getBytes(), c.getLargeVarChar(VARCHAR_VECTOR_NAME_1)); + assertArrayEquals("two".getBytes(), c.getLargeVarChar(1)); } } From 0c2c151617e959815d010805ac37228579f973cc Mon Sep 17 00:00:00 2001 From: Larry White Date: Tue, 4 Oct 2022 14:40:44 -0400 Subject: [PATCH 36/40] undo temp changes to pom --- java/pom.xml | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/java/pom.xml b/java/pom.xml index 95e787c1e48..0438bb8fda8 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -43,10 +43,8 @@ 2 true - 3.10.1 @@ -305,9 +303,9 @@ 8.19 - org.slf4j - jcl-over-slf4j - 1.7.5 + org.slf4j + jcl-over-slf4j + 1.7.5 @@ -751,7 +749,7 @@ shade-flatbuffers - shade-format-flatbuffers + shade-format-flatbuffers @@ -765,7 +763,7 @@ 1.8 - !m2e.version + !m2e.version @@ -777,12 +775,9 @@ true -XDcompilePolicy=simple - - @@ -816,9 +810,7 @@ UTF-8 -XDcompilePolicy=simple - -J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED @@ -830,7 +822,6 @@ -J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED -J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED - From fc008504aa5ffa11b8d8d8538da3fffc616fe103 Mon Sep 17 00:00:00 2001 From: Larry White Date: Wed, 5 Oct 2022 08:28:44 -0400 Subject: [PATCH 37/40] Add apache license text to README.md --- .../org/apache/arrow/vector/table/README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md index a0a0c6bf0cf..b9b9192846b 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md @@ -1,3 +1,22 @@ + + # Table **NOTE**: The API is experimental and subject to change. See the list of limitations below. From 983f311792c1b9cb302046e70e6e22040b812dc8 Mon Sep 17 00:00:00 2001 From: Larry White Date: Wed, 5 Oct 2022 12:37:51 -0400 Subject: [PATCH 38/40] fix readme issues --- .../org/apache/arrow/vector/table/README.md | 129 ++++++++---------- 1 file changed, 59 insertions(+), 70 deletions(-) diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md index b9b9192846b..4614a75dbf7 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md @@ -44,16 +44,16 @@ _Table_, on the other hand, is immutable. The underlying vectors are not exposed ## Features and limitations ### Features -A basic set of table functionality is included in this release: +A basic set of table functionality is included in this release: - Create a Table from FieldVectors or VectorSchemaRoot - Iterate tables by row or set the current row index directly - Access Vector values as primitives, objects, and/or NullableHolders (depending on type) - Get FieldReader for any vector -- Add and remove FieldVectors +- Add and remove FieldVectors - Encode and decode a table's vectors using DictionaryEncoding - Export Table memory for use by native code -- Print first rows to Strings +- Print first rows to Strings - Get table schema - Slice tables - Convert table to VectorSchemaRoot @@ -78,7 +78,7 @@ Like VectorSchemaRoot, Table consists of a `Schema` and an ordered collection of Tables are created from a VectorSchemaRoot as shown below. The memory buffers holding the data are transferred from the VectorSchemaRoot to new vectors in the new Table, clearing the original VectorSchemaRoot in the process. This ensures that the data in your new Table is never changed. Since the buffers are transferred rather than copied, this is a very low overhead operation. ```java -VectorSchemaRoot vsr = getMyVsr(); + VectorSchemaRoot vsr = getMyVsr(); Table t = new Table(vsr); ``` @@ -91,14 +91,14 @@ If you now update the FieldVectors used to create the VectorSchemaRoot (using so Tables can be created from ValueVectors as shown below. ```java -IntVector myVector = createMyIntVector(); + IntVector myVector = createMyIntVector(); VectorSchemaRoot vsr1 = new VectorSchemaRoot(myVector); ``` or ```java -IntVector myVector = createMyIntVector(); + IntVector myVector = createMyIntVector(); List fvList = List.of(myVector); VectorSchemaRoot vsr1 = new VectorSchemaRoot(fvList); ``` @@ -108,10 +108,10 @@ It is rarely a good idea to share vectors between multiple VectorSchemaRoots, an *Don't do this:* ```Java -IntVector myVector = createMyIntVector(); // Reference count for myVector = 1 + IntVector myVector = createMyIntVector(); // Reference count for myVector = 1 VectorSchemaRoot vsr1 = new VectorSchemaRoot(myVector); // Still one reference VectorSchemaRoot vsr2 = new VectorSchemaRoot(myVector); -// Ref count is still one, but there are two VSRs with a reference to myVector + // Ref count is still one, but there are two VSRs with a reference to myVector vsr2.clear(); // Reference count for myVector is 0. ``` @@ -122,7 +122,7 @@ When you create Tables from vectors, it's assumed that there are no external ref *Don't do this either, but note the difference from above:* ```Java -IntVector myVector = createMyIntVector(); // Reference count for myVector = 1 + IntVector myVector = createMyIntVector(); // Reference count for myVector = 1 Table t1 = new Table(myVector); // myVector is cleared; Table t1 has a new hidden vector with // the data from myVector Table t2 = new Table(myVector); // t2 has no rows because the myVector was just cleared @@ -139,7 +139,7 @@ With Tables, memory is explicitly transferred on instantiatlon so the buffers ar Another point of difference is that dictionary-encoding is managed separately from VectorSchemaRoot, while Tables hold an optional DictionaryProvider instance. If any vectors in the source data are encoded, a DictionaryProvider must be set to un-encode the values. ```java -VectorSchemaRoot vsr = myVsr(); + VectorSchemaRoot vsr = myVsr(); DictionaryProvider provider = myProvider(); Table t = new Table(vsr, provider); ``` @@ -147,21 +147,19 @@ VectorSchemaRoot vsr = myVsr(); In the immutable Table case, dictionaries are used in a way that's similar to the approach used with ValueVectors. To decode a vector, the user provides the dictionary id and the name of the vector to decode: ```Java -Table t = new Table(vsr, provider); + Table t = new Table(vsr, provider); ValueVector decodedName = t.decode("name", 1L); ``` To encode a vector from a table, a similar approach is used: ```Java -Table t = new Table(vsr, provider); + Table t = new Table(vsr, provider); ValueVector encodedName = t.encode("name", 1L); ``` -***Current Limitation:*** One difference is the method that produces TSV formatted output has an extra switch instructing the Table to replace the encoded output with the decoded output where possible: - ```java -String output = myTable.contentToTSVString(true); + String output = myTable.contentToTSVString(true); ``` ### Freeing memory explicitly @@ -169,22 +167,22 @@ String output = myTable.contentToTSVString(true); Tables use off-heap memory that must be freed when it is no longer needed. Table implements AutoCloseable so the best way to create one is in a try-with-resources block: ```java -try (VectorSchemaRoot vsr = myMethodForGettingVsrs(); - Table t = new Table(vsr)) { - // do useful things. + try (VectorSchemaRoot vsr = myMethodForGettingVsrs(); + Table t = new Table(vsr)) { + // do useful things. } ``` If you don't use a try-with-resources block, you must close the Table manually: ````java -try { - VectorSchemaRoot vsr = myMethodForGettingVsrs(); - Table t = new Table(vsr); - // do useful things. + try { + VectorSchemaRoot vsr = myMethodForGettingVsrs(); + Table t = new Table(vsr); + // do useful things. } finally { - vsr.close(); - t.close(); + vsr.close(); + t.close(); } ```` @@ -195,7 +193,7 @@ Manually closing should be performed in a finally block. You get the table's schema the same way you do with a VectorSchemaRoot: ```java -Schema s = table.getSchema(); + Schema s = table.getSchema(); ``` ## Table API: Adding and removing vectors @@ -203,11 +201,11 @@ Schema s = table.getSchema(); Table provides facilities for adding and removing FieldVectors modeled on the same functionality in VectorSchemaRoot. As with VectorSchemaRoot, these operations return new instances rather than modifiying the original instance in-place. ```java -try (Table t = new Table(vectorList)) { - IntVector v3 = new IntVector("3", intFieldType, allocator); - Table t2 = t.addVector(2, v3); - Table t3 = t2.removeVector(1); - // don't forget to close t2 and t3 + try (Table t = new Table(vectorList)) { + IntVector v3 = new IntVector("3", intFieldType, allocator); + Table t2 = t.addVector(2, v3); + Table t3 = t2.removeVector(1); + // don't forget to close t2 and t3 } ``` @@ -216,18 +214,18 @@ try (Table t = new Table(vectorList)) { Table supports *slice()* operations, where a slice of a source table is a second Table that refers to a single, contiguous range of rows in the source. ```Java -try (Table t = new Table(vectorList)) { - Table t2 = t.slice(100, 200); // creates a slice referencing the values in range (100, 200] - ... + try (Table t = new Table(vectorList)) { + Table t2 = t.slice(100, 200); // creates a slice referencing the values in range (100, 200] + ... } ``` If you created a slice with *all* the values in the source table (as shown below), how would that differ from a new Table constructed with the same vectors as the source? ```Java -try (Table t = new Table(vectorList)) { - Table t2 = t.slice(0, t.getRowCount()); // creates a slice referencing all the values in t - // ... + try (Table t = new Table(vectorList)) { + Table t2 = t.slice(0, t.getRowCount()); // creates a slice referencing all the values in t + // ... } ``` @@ -240,7 +238,7 @@ Slices will not be supported in MutableTables. You can get a FieldReader for any vector in the Table using either the Field, vector index, or vector name. The signatures are the same as in VectorSchemaRoot. ```java -FieldReader nameReader = table.getReader("user_name"); + FieldReader nameReader = table.getReader("user_name"); ``` ## Table API: Row operations @@ -254,7 +252,7 @@ Row-based access is supported using a Row object. Row provides *get()* methods b Calling `immutableRow()` on any table instance returns a row supporting read operations. ```java -Row r = table.immutableRow(); + Row r = table.immutableRow(); ``` ### Getting around @@ -262,28 +260,28 @@ Row r = table.immutableRow(); Since rows are iterable, you can traverse a table using a standard while loop: ```java -Row r = table.immutableRow(); - while (c.hasNext()) { - c.next(); - // do something useful here + Row r = table.immutableRow(); + while (r.hasNext()) { + r.next(); + // do something useful here } ``` Table implements `Iterable` so you can access rows directly from Table in an enhanced *for* loop: ```java -for (Row row: table) { - int age = row.getInt("age"); - boolean nameIsNull = row.isNull("name"); - ... + for (Row row: table) { + int age = row.getInt("age"); + boolean nameIsNull = row.isNull("name"); + ... } ``` Finally, while rows are usually iterated in the order of the underlying data vectors, but they are also positionable using the `Row#setPosition()` method, so you can skip to a specific row. Row numbers are 0-based. ```java -Row r = table.immutableRow(); - int age101 = c.setPosition(101); // change position directly to 101 + Row r = table.immutableRow(); + int age101 = r.setPosition(101); // change position directly to 101 ``` Any changes to position are of course applied to all the columns in the table. @@ -295,16 +293,17 @@ Note that you must call `next()`, or `setPosition()` before accessing values via Methods are available for getting values by vector name and vector index, where index is the 0-based position of the vector in the table. For example, assuming 'age' is the 13th vector in 'table', the following two gets are equivalent: ```java -Row r = table.immutableRow(); - c.next(); // position the row at the first value - int age1 = c.get("age"); // gets the value of vector named 'age' in the table at row 0 - int age2 = c.get(12); // gets the value of the 13th vecto in the table at row 0 + Row r = table.immutableRow(); + r.next(); // position the row at the first value + int age1 = r.get("age"); // gets the value of vector named 'age' in the table at row 0 + int age2 = r.get(12); // gets the value of the 13th vecto in the table at row 0 ``` You can also get value using a NullableHolder. For example: ```Java -NullableIntHolder holder = new NullableIntHolder(); + + NullableIntHolder holder = new NullableIntHolder(); int b = row.getInt("age", holder); ``` @@ -313,7 +312,7 @@ This can be used to retrieve values without creating a new Object for each. In addition to getting values, you can check if a value is null using `isNull()` and you can get the current row number: ```java -boolean name0isNull = row.isNull("name"); + boolean name0isNull = row.isNull("name"); int row = row.getRowNumber(); ``` @@ -324,7 +323,7 @@ Note that while there are getters for most vector types (e.g. *getInt()* for use For any given vector type, the basic *get()* method returns a primitive value wherever possible. For example, *getTimeStampMicro()* returns a long value that encodes the timestamp. To get the LocalDateTime object representing that timestamp in Java, another method with 'Obj' appended to the name is provided. For example: ```java -long ts = row.getTimeStampMicro(); + long ts = row.getTimeStampMicro(); LocalDateTime tsObject = row.getTimeStampMicroObj(); ``` @@ -335,8 +334,8 @@ The exception to this naming scheme is for complex vector types (List, Map, Sche Strings in arrow are represented as byte arrays, encoded with the UTF-8 charset as this is the only character set supported in the Arrow format. You can get either a String result or the actual byte array. ```Java -byte[] b = row.getVarChar("first_name"); -String s = row.getVarCharObj("first_name"); // uses the default encoding (UTF-8) + byte[] b = row.getVarChar("first_name"); + String s = row.getVarCharObj("first_name"); // uses the default encoding (UTF-8) ``` ## Table API: Converting a Table to a VectorSchemaRoot @@ -344,7 +343,7 @@ String s = row.getVarCharObj("first_name"); // uses the default encoding ( Tables can be converted to VectorSchemaRoot objects using the *toVectorSchemaRoot()* method. ```java -VectorSchemaRoot root = myTable.toVectorSchemaRoot(); + VectorSchemaRoot root = myTable.toVectorSchemaRoot(); ``` Buffers are transferred to the VectorSchemaRoot and the Table is cleared. @@ -358,13 +357,13 @@ The ability to work with native code is required for many Arrow features. This s This works by converting the data to a VectorSchemaRoot and using the existing facilities for transferring the data. This would not generally be ideal because conversion to a VectorSchemaRoot breaks the immutability guarantees. Using the static utility methods defined in the class org.apache.arrow.c.Data` avoids this concern because the vector schema root used is not expored. See the example code below: ```java -Data.exportTable(bufferAllocator, table, dictionaryProvider, outArrowArray); + Data.exportTable(bufferAllocator, table, dictionaryProvider, outArrowArray); ``` If the table contains dictionary-encoded vectors, it should have been created with a dictionary provider to support encode and decode operations. In that case, the provider argument can be ommitted and the table's provider attribute will be used: ```java -Data.exportTable(bufferAllocator, table, outArrowArray); + Data.exportTable(bufferAllocator, table, outArrowArray); ``` ### Importing Tables from native code @@ -372,13 +371,3 @@ Data.exportTable(bufferAllocator, table, outArrowArray); ***Current limitation: Data imported from native code using the C-Data-interface cannot be used in a table, because the current implementation of CDataReferenceManager does not support the transfer operation.*** ## Table API: Working with the C-Stream interface - -***Current limitation: Streaming API is not currently supported. Support is planned for a future release.*** - -The following are the major limitations of v. 10.0.0 release: - -1. No support ChunkedArrays or any form of row-group. Support for ChunkedArrows or row groups will be considered for a future release. -2. No support for native interface using the C-Stream API. Support for the streaming API will be delivered with or after Item 1. -3. No ability to use Tables with data imported from native code using the C-Data API. Support for ths feature is gated on PR#13248 (https://github.com/apache/arrow/pull/13248). -4. No support for creating tables directly from Java POJOs. All data held by a table must be imported via a VectorSchemaRoot, or from collections or arrays of FieldVectors. -5. No support for mutable tables. From c844047b304e7c9db1f72505fff83152b9bf17c7 Mon Sep 17 00:00:00 2001 From: Larry White Date: Wed, 5 Oct 2022 12:39:57 -0400 Subject: [PATCH 39/40] Restore line erroneously deleted --- .../src/main/java/org/apache/arrow/vector/table/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md index 4614a75dbf7..032095f355b 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/README.md +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/README.md @@ -371,3 +371,5 @@ If the table contains dictionary-encoded vectors, it should have been created wi ***Current limitation: Data imported from native code using the C-Data-interface cannot be used in a table, because the current implementation of CDataReferenceManager does not support the transfer operation.*** ## Table API: Working with the C-Stream interface + +***Current limitation: Streaming API is not currently supported. Support is planned for a future release.*** From 3887d8cc90c399c119f49d6790c7d0f750c685ea Mon Sep 17 00:00:00 2001 From: Larry White Date: Wed, 5 Oct 2022 14:12:49 -0400 Subject: [PATCH 40/40] Removes BaseRow class and converts CharSet variable to static --- .../apache/arrow/vector/table/BaseRow.java | 65 ------------------- .../org/apache/arrow/vector/table/Row.java | 28 ++++++-- 2 files changed, 23 insertions(+), 70 deletions(-) delete mode 100644 java/vector/src/main/java/org/apache/arrow/vector/table/BaseRow.java diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/BaseRow.java b/java/vector/src/main/java/org/apache/arrow/vector/table/BaseRow.java deleted file mode 100644 index 9d400c8f189..00000000000 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/BaseRow.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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.table; - -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; - -/** - * Provides row based access to the data held by a {@link Table}. - * - *

    - * This API is EXPERIMENTAL. - */ -public abstract class BaseRow { - - /** The table we're enumerating. */ - protected final BaseTable table; - - /** the current row number. */ - protected int rowNumber = -1; - - /** - * Returns the standard character set to use for decoding strings. The Arrow format only supports UTF-8. - */ - private final Charset defaultCharacterSet = StandardCharsets.UTF_8; - - /** - * Constructs a new BaseRow backed by the given table. - * - * @param table the table that this MutableCursor object represents - */ - public BaseRow(BaseTable table) { - this.table = table; - } - - /** - * Resets the row index to -1 and returns this object. - */ - BaseRow resetPosition() { - rowNumber = -1; - return this; - } - - /** - * Returns the default character set for use with character vectors. - */ - public Charset getDefaultCharacterSet() { - return defaultCharacterSet; - } -} diff --git a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java index e09ef219f98..b6cc566f2f7 100644 --- a/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java +++ b/java/vector/src/main/java/org/apache/arrow/vector/table/Row.java @@ -18,6 +18,8 @@ package org.apache.arrow.vector.table; import java.math.BigDecimal; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.time.Duration; import java.time.LocalDateTime; import java.time.Period; @@ -105,8 +107,17 @@ *

    * This API is EXPERIMENTAL. */ -public class Row extends BaseRow implements Iterator { +public class Row implements Iterator { + /** + * Returns the standard character set to use for decoding strings. The Arrow format only supports UTF-8. + */ + private static final Charset DEFAULT_CHARACTER_SET = StandardCharsets.UTF_8; + + /** The table we're enumerating. */ + protected final BaseTable table; + /** the current row number. */ + protected int rowNumber = -1; /** Indicates whether the next non-deleted row has been determined yet. */ private boolean nextRowSet; @@ -117,20 +128,20 @@ public class Row extends BaseRow implements Iterator { private final Iterator iterator = intIterator(); /** - * Constructs a new BaseRow backed by the given table. + * Constructs a new Row backed by the given table. * * @param table the table that this Row object represents */ public Row(BaseTable table) { - super(table); + this.table = table; } /** * Resets the current row to -1 and returns this object. */ - @Override public Row resetPosition() { - return (Row) super.resetPosition(); + rowNumber = -1; + return this; } /** @@ -1831,4 +1842,11 @@ public int getRowNumber() { private boolean rowIsDeleted(int rowNumber) { return table.isRowDeleted(rowNumber); } + + /** + * Returns the default character set for use with character vectors. + */ + public Charset getDefaultCharacterSet() { + return DEFAULT_CHARACTER_SET; + } }