From ef349c68932c1606a7e3c8789ffcc96d95c4175e Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Mon, 23 Oct 2023 15:27:49 +0000 Subject: [PATCH 01/21] Add parameter binding for Prepared Statements --- .../driver/jdbc/ArrowFlightJdbcFactory.java | 9 -- .../ArrowFlightJdbcFlightStreamResultSet.java | 2 +- ...owFlightJdbcVectorSchemaRootResultSet.java | 12 +- .../driver/jdbc/ArrowFlightMetaImpl.java | 74 ++++++---- .../jdbc/ArrowFlightPreparedStatement.java | 33 ----- .../client/ArrowFlightSqlClientHandler.java | 20 +++ .../driver/jdbc/utils/ArrowToJdbcUtils.java | 123 +++++++++++++++++ .../arrow/driver/jdbc/utils/ConvertUtils.java | 22 ++- .../driver/jdbc/utils/TypedValueBinder.java | 129 ++++++++++++++++++ 9 files changed, 346 insertions(+), 78 deletions(-) create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/TypedValueBinder.java diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcFactory.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcFactory.java index 216e4cd002bc3..16bdede02d039 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcFactory.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcFactory.java @@ -17,8 +17,6 @@ package org.apache.arrow.driver.jdbc; -import static org.apache.arrow.driver.jdbc.utils.ConvertUtils.convertArrowFieldsToColumnMetaDataList; - import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.Properties; @@ -26,7 +24,6 @@ import org.apache.arrow.driver.jdbc.client.ArrowFlightSqlClientHandler; import org.apache.arrow.memory.RootAllocator; -import org.apache.arrow.vector.types.pojo.Schema; import org.apache.calcite.avatica.AvaticaConnection; import org.apache.calcite.avatica.AvaticaFactory; import org.apache.calcite.avatica.AvaticaResultSetMetaData; @@ -89,12 +86,6 @@ public ArrowFlightPreparedStatement newPreparedStatement( ArrowFlightSqlClientHandler.PreparedStatement preparedStatement = flightConnection.getMeta().getPreparedStatement(statementHandle); - if (preparedStatement == null) { - preparedStatement = flightConnection.getClientHandler().prepare(signature.sql); - } - final Schema resultSetSchema = preparedStatement.getDataSetSchema(); - signature.columns.addAll(convertArrowFieldsToColumnMetaDataList(resultSetSchema.getFields())); - return ArrowFlightPreparedStatement.newPreparedStatement( flightConnection, preparedStatement, statementHandle, signature, resultType, resultSetConcurrency, resultSetHoldability); diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcFlightStreamResultSet.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcFlightStreamResultSet.java index 9a53f9fcafdd2..299e7ccfb4298 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcFlightStreamResultSet.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcFlightStreamResultSet.java @@ -92,7 +92,7 @@ static ArrowFlightJdbcFlightStreamResultSet fromFlightInfo( final TimeZone timeZone = TimeZone.getDefault(); final QueryState state = new QueryState(); - final Meta.Signature signature = ArrowFlightMetaImpl.newSignature(null); + final Meta.Signature signature = ArrowFlightMetaImpl.newSignature(null, null, null); final AvaticaResultSetMetaData resultSetMetaData = new AvaticaResultSetMetaData(null, null, signature); diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcVectorSchemaRootResultSet.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcVectorSchemaRootResultSet.java index 9e377e51decc9..0c6d5e6161ea6 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcVectorSchemaRootResultSet.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcVectorSchemaRootResultSet.java @@ -17,20 +17,18 @@ package org.apache.arrow.driver.jdbc; -import static java.util.Objects.isNull; - import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.TimeZone; import org.apache.arrow.driver.jdbc.utils.ConvertUtils; import org.apache.arrow.util.AutoCloseables; import org.apache.arrow.vector.VectorSchemaRoot; -import org.apache.arrow.vector.types.pojo.Field; import org.apache.arrow.vector.types.pojo.Schema; import org.apache.calcite.avatica.AvaticaResultSet; import org.apache.calcite.avatica.AvaticaResultSetMetaData; @@ -74,7 +72,7 @@ public static ArrowFlightJdbcVectorSchemaRootResultSet fromVectorSchemaRoot( final TimeZone timeZone = TimeZone.getDefault(); final QueryState state = new QueryState(); - final Meta.Signature signature = ArrowFlightMetaImpl.newSignature(null); + final Meta.Signature signature = ArrowFlightMetaImpl.newSignature(null, null, null); final AvaticaResultSetMetaData resultSetMetaData = new AvaticaResultSetMetaData(null, null, signature); @@ -93,8 +91,8 @@ protected AvaticaResultSet execute() throws SQLException { } void execute(final VectorSchemaRoot vectorSchemaRoot) { - final List fields = vectorSchemaRoot.getSchema().getFields(); - final List columns = ConvertUtils.convertArrowFieldsToColumnMetaDataList(fields); + final List columns = ConvertUtils.convertArrowFieldsToColumnMetaDataList( + vectorSchemaRoot.getSchema().getFields()); signature.columns.clear(); signature.columns.addAll(columns); @@ -137,7 +135,7 @@ public void close() { } catch (final Exception e) { exceptions.add(e); } - if (!isNull(statement)) { + if (!Objects.isNull(statement)) { try { super.close(); } catch (final Exception e) { diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java index f825e7d13cef5..ec721a9b5dbdc 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java @@ -17,8 +17,6 @@ package org.apache.arrow.driver.jdbc; -import static java.lang.String.format; - import java.sql.Connection; import java.sql.SQLException; import java.sql.SQLTimeoutException; @@ -29,7 +27,10 @@ import java.util.concurrent.ConcurrentHashMap; import org.apache.arrow.driver.jdbc.client.ArrowFlightSqlClientHandler.PreparedStatement; +import org.apache.arrow.driver.jdbc.utils.ConvertUtils; +import org.apache.arrow.driver.jdbc.utils.TypedValueBinder; import org.apache.arrow.util.Preconditions; +import org.apache.arrow.vector.types.pojo.Schema; import org.apache.calcite.avatica.AvaticaConnection; import org.apache.calcite.avatica.AvaticaParameter; import org.apache.calcite.avatica.ColumnMetaData; @@ -54,12 +55,20 @@ public ArrowFlightMetaImpl(final AvaticaConnection connection) { setDefaultConnectionProperties(); } - static Signature newSignature(final String sql) { + /** + * Construct a signature with only the SQL query. Column metadata and parameters must be filled out elsewhere. + */ + static Signature newSignature(final String sql, Schema resultSetSchema, Schema parameterSchema) { + List columnMetaData = resultSetSchema == null ? + new ArrayList<>() : ConvertUtils.convertArrowFieldsToColumnMetaDataList(resultSetSchema.getFields()); + List parameters = parameterSchema == null ? + new ArrayList<>() : ConvertUtils.convertArrowFieldsToAvaticaParameters(parameterSchema.getFields()); + return new Signature( - new ArrayList(), + columnMetaData, sql, - Collections.emptyList(), - Collections.emptyMap(), + parameters, + Collections.emptyMap(), null, // unnecessary, as SQL requests use ArrowFlightJdbcCursor StatementType.SELECT ); @@ -84,23 +93,30 @@ public void commit(final ConnectionHandle connectionHandle) { public ExecuteResult execute(final StatementHandle statementHandle, final List typedValues, final long maxRowCount) { Preconditions.checkArgument(connection.id.equals(statementHandle.connectionId), - "Connection IDs are not consistent"); + "Connection IDs are not consistent"); + final StatementHandleKey key = new StatementHandleKey(statementHandle); + PreparedStatement preparedStatement = statementHandlePreparedStatementMap.get(key); + + if (preparedStatement == null) { + throw new IllegalStateException("Prepared statement not found: " + statementHandle); + } + + try (final TypedValueBinder binder = + new TypedValueBinder(preparedStatement, ((ArrowFlightConnection) connection).getBufferAllocator())) { + binder.bind(typedValues); + } + if (statementHandle.signature == null) { // Update query - final StatementHandleKey key = new StatementHandleKey(statementHandle); - PreparedStatement preparedStatement = statementHandlePreparedStatementMap.get(key); - if (preparedStatement == null) { - throw new IllegalStateException("Prepared statement not found: " + statementHandle); - } long updatedCount = preparedStatement.executeUpdate(); return new ExecuteResult(Collections.singletonList(MetaResultSet.count(statementHandle.connectionId, - statementHandle.id, updatedCount))); + statementHandle.id, updatedCount))); } else { // TODO Why is maxRowCount ignored? return new ExecuteResult( - Collections.singletonList(MetaResultSet.create( - statementHandle.connectionId, statementHandle.id, - true, statementHandle.signature, null))); + Collections.singletonList(MetaResultSet.create( + statementHandle.connectionId, statementHandle.id, + true, statementHandle.signature, null))); } } @@ -126,18 +142,24 @@ public Frame fetch(final StatementHandle statementHandle, final long offset, * the results. */ throw AvaticaConnection.HELPER.wrap( - format("%s does not use frames.", this), + String.format("%s does not use frames.", this), AvaticaConnection.HELPER.unsupported()); } + private PreparedStatement prepareForHandle(final String query, StatementHandle handle) { + final PreparedStatement preparedStatement = + ((ArrowFlightConnection) connection).getClientHandler().prepare(query); + handle.signature = newSignature(query, preparedStatement.getDataSetSchema(), + preparedStatement.getParameterSchema()); + statementHandlePreparedStatementMap.put(new StatementHandleKey(handle), preparedStatement); + return preparedStatement; + } + @Override public StatementHandle prepare(final ConnectionHandle connectionHandle, final String query, final long maxRowCount) { final StatementHandle handle = super.createStatement(connectionHandle); - handle.signature = newSignature(query); - final PreparedStatement preparedStatement = - ((ArrowFlightConnection) connection).getClientHandler().prepare(query); - statementHandlePreparedStatementMap.put(new StatementHandleKey(handle), preparedStatement); + prepareForHandle(query, handle); return handle; } @@ -157,20 +179,18 @@ public ExecuteResult prepareAndExecute(final StatementHandle handle, final PrepareCallback callback) throws NoSuchStatementException { try { - final PreparedStatement preparedStatement = - ((ArrowFlightConnection) connection).getClientHandler().prepare(query); + PreparedStatement preparedStatement = prepareForHandle(query, handle); final StatementType statementType = preparedStatement.getType(); - statementHandlePreparedStatementMap.put(new StatementHandleKey(handle), preparedStatement); - final Signature signature = newSignature(query); + final long updateCount = statementType.equals(StatementType.UPDATE) ? preparedStatement.executeUpdate() : -1; synchronized (callback.getMonitor()) { callback.clear(); - callback.assign(signature, null, updateCount); + callback.assign(handle.signature, null, updateCount); } callback.execute(); final MetaResultSet metaResultSet = MetaResultSet.create(handle.connectionId, handle.id, - false, signature, null); + false, handle.signature, null); return new ExecuteResult(Collections.singletonList(metaResultSet)); } catch (SQLTimeoutException e) { // So far AvaticaStatement(executeInternal) only handles NoSuchStatement and Runtime Exceptions. diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatement.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatement.java index 8784e39840b6a..7203f02daa9a1 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatement.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatement.java @@ -17,15 +17,12 @@ package org.apache.arrow.driver.jdbc; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import org.apache.arrow.driver.jdbc.client.ArrowFlightSqlClientHandler; -import org.apache.arrow.driver.jdbc.utils.ConvertUtils; import org.apache.arrow.flight.FlightInfo; import org.apache.arrow.util.Preconditions; -import org.apache.arrow.vector.types.pojo.Schema; import org.apache.calcite.avatica.AvaticaPreparedStatement; import org.apache.calcite.avatica.Meta.Signature; import org.apache.calcite.avatica.Meta.StatementHandle; @@ -50,36 +47,6 @@ private ArrowFlightPreparedStatement(final ArrowFlightConnection connection, this.preparedStatement = Preconditions.checkNotNull(preparedStatement); } - /** - * Creates a new {@link ArrowFlightPreparedStatement} from the provided information. - * - * @param connection the {@link Connection} to use. - * @param statementHandle the {@link StatementHandle} to use. - * @param signature the {@link Signature} to use. - * @param resultSetType the ResultSet type. - * @param resultSetConcurrency the ResultSet concurrency. - * @param resultSetHoldability the ResultSet holdability. - * @return a new {@link PreparedStatement}. - * @throws SQLException on error. - */ - static ArrowFlightPreparedStatement createNewPreparedStatement( - final ArrowFlightConnection connection, - final StatementHandle statementHandle, - final Signature signature, - final int resultSetType, - final int resultSetConcurrency, - final int resultSetHoldability) throws SQLException { - - final ArrowFlightSqlClientHandler.PreparedStatement prepare = connection.getClientHandler().prepare(signature.sql); - final Schema resultSetSchema = prepare.getDataSetSchema(); - - signature.columns.addAll(ConvertUtils.convertArrowFieldsToColumnMetaDataList(resultSetSchema.getFields())); - - return new ArrowFlightPreparedStatement( - connection, prepare, statementHandle, - signature, resultSetType, resultSetConcurrency, resultSetHoldability); - } - static ArrowFlightPreparedStatement newPreparedStatement(final ArrowFlightConnection connection, final ArrowFlightSqlClientHandler.PreparedStatement preparedStmt, final StatementHandle statementHandle, diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/client/ArrowFlightSqlClientHandler.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/client/ArrowFlightSqlClientHandler.java index bb1d524aca008..a2790968dd145 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/client/ArrowFlightSqlClientHandler.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/client/ArrowFlightSqlClientHandler.java @@ -48,6 +48,7 @@ import org.apache.arrow.memory.BufferAllocator; import org.apache.arrow.util.AutoCloseables; import org.apache.arrow.util.Preconditions; +import org.apache.arrow.vector.VectorSchemaRoot; import org.apache.arrow.vector.types.pojo.Schema; import org.apache.calcite.avatica.Meta.StatementType; import org.slf4j.Logger; @@ -155,6 +156,15 @@ public interface PreparedStatement extends AutoCloseable { */ Schema getDataSetSchema(); + /** + * Gets the {@link Schema} of the parameters for this {@link PreparedStatement}. + * + * @return {@link Schema}. + */ + Schema getParameterSchema(); + + void setParameters(VectorSchemaRoot parameters); + @Override void close(); } @@ -190,6 +200,16 @@ public Schema getDataSetSchema() { return preparedStatement.getResultSetSchema(); } + @Override + public Schema getParameterSchema() { + return preparedStatement.getParameterSchema(); + } + + @Override + public void setParameters(VectorSchemaRoot parameters) { + preparedStatement.setParameters(parameters); + } + @Override public void close() { try { diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java new file mode 100644 index 0000000000000..8e9384e577373 --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java @@ -0,0 +1,123 @@ +/* + * 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.driver.jdbc.utils; + +import java.math.BigDecimal; +import java.sql.Date; +import java.sql.Time; +import java.sql.Timestamp; +import java.sql.Types; +import java.util.ArrayList; +import java.util.HashMap; + +import org.apache.arrow.vector.types.pojo.ArrowType; + +/** + * Helper class to convert Arrow types to JDBC required values. + */ +class ArrowToJdbcUtils { + static boolean isSigned(ArrowType.ArrowTypeID type) { + switch (type) { + case Int: + case FloatingPoint: + case Decimal: + case Interval: + case Duration: + return true; + default: + return false; + } + } + + static int toJdbcType(ArrowType type) { + switch (type.getTypeID()) { + case Null: + return Types.NULL; + case Struct: + return Types.STRUCT; + case List: + case LargeList: + case FixedSizeList: + return Types.ARRAY; + case Int: + return ((ArrowType.Int) type).getBitWidth() == 64 ? Types.BIGINT : Types.INTEGER; + case FloatingPoint: + return Types.FLOAT; + case Utf8: + case LargeUtf8: + return Types.VARCHAR; + case Binary: + case LargeBinary: + return Types.VARBINARY; + case FixedSizeBinary: + return Types.BINARY; + case Bool: + return Types.BOOLEAN; + case Decimal: + return Types.DECIMAL; + case Date: + return Types.DATE; + case Time: + return Types.TIME; + case Timestamp: + case Interval: + case Duration: + return Types.TIMESTAMP; + default: + return Types.OTHER; + } + + } + + static String getClassName(ArrowType type) { + switch (type.getTypeID()) { + case List: + case LargeList: + case FixedSizeList: + return ArrayList.class.getCanonicalName(); + case Map: + return HashMap.class.getCanonicalName(); + case Int: + return ((ArrowType.Int) type).getBitWidth() == 64 ? + long.class.getCanonicalName() : int.class.getCanonicalName(); + case FloatingPoint: + return float.class.getCanonicalName(); + case Utf8: + case LargeUtf8: + return String.class.getCanonicalName(); + case Binary: + case LargeBinary: + case FixedSizeBinary: + return byte[].class.getCanonicalName(); + case Bool: + return boolean.class.getCanonicalName(); + case Decimal: + return BigDecimal.class.getCanonicalName(); + case Date: + return Date.class.getCanonicalName(); + case Time: + return Time.class.getCanonicalName(); + case Timestamp: + case Interval: + case Duration: + return Timestamp.class.getCanonicalName(); + default: + return null; + } + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java index 324f991ef09e9..d6bb8678e0d80 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java @@ -25,12 +25,13 @@ import org.apache.arrow.flight.sql.FlightSqlColumnMetadata; import org.apache.arrow.vector.types.pojo.ArrowType; import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; import org.apache.calcite.avatica.ColumnMetaData; import org.apache.calcite.avatica.proto.Common; import org.apache.calcite.avatica.proto.Common.ColumnMetaData.Builder; /** - * Convert Fields To Column MetaData List functions. + * Convert objects between Arrow and Avatica. */ public final class ConvertUtils { @@ -113,4 +114,23 @@ public static void setOnColumnMetaDataBuilder(final Builder builder, builder.setSearchable(searchable); } } + + /** + * Convert Fields To Avatica Parameters. + * + * @param fields list of {@link Field}. + * @return list of {@link AvaticaParameter}. + */ + public static List convertArrowFieldsToAvaticaParameters(final List fields) { + return fields.stream().map(field -> { + final boolean signed = ArrowToJdbcUtils.isSigned(field.getType().getTypeID()); + final int precision = 0; // Would have to know about the actual number + final int scale = 0; // According to https://www.postgresql.org/docs/current/datatype-numeric.html + final int type = ArrowToJdbcUtils.toJdbcType(field.getType()); + final String typeName = field.getType().toString(); + final String clazz = ArrowToJdbcUtils.getClassName(field.getType()); + final String name = field.getName(); + return new AvaticaParameter(signed, precision, scale, type, typeName, clazz, name); + }).collect(Collectors.toList()); + } } diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/TypedValueBinder.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/TypedValueBinder.java new file mode 100644 index 0000000000000..de35f86b1926a --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/TypedValueBinder.java @@ -0,0 +1,129 @@ +/* + * 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.driver.jdbc.utils; + +import java.math.BigDecimal; +import java.util.List; + +import org.apache.arrow.driver.jdbc.client.ArrowFlightSqlClientHandler.PreparedStatement; +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.vector.BigIntVector; +import org.apache.arrow.vector.BitVector; +import org.apache.arrow.vector.DateMilliVector; +import org.apache.arrow.vector.DecimalVector; +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.Float4Vector; +import org.apache.arrow.vector.Float8Vector; +import org.apache.arrow.vector.IntVector; +import org.apache.arrow.vector.LargeVarBinaryVector; +import org.apache.arrow.vector.LargeVarCharVector; +import org.apache.arrow.vector.NullVector; +import org.apache.arrow.vector.VarBinaryVector; +import org.apache.arrow.vector.VarCharVector; +import org.apache.arrow.vector.VectorSchemaRoot; +import org.apache.arrow.vector.util.Text; +import org.apache.calcite.avatica.remote.TypedValue; +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; + +/** + * Bind {@link TypedValue}s to a {@link VectorSchemaRoot}. + */ +public class TypedValueBinder implements AutoCloseable { + private final PreparedStatement preparedStatement; + private final VectorSchemaRoot parameters; + + public TypedValueBinder(PreparedStatement preparedStatement, BufferAllocator bufferAllocator) { + this.parameters = VectorSchemaRoot.create(preparedStatement.getParameterSchema(), bufferAllocator); + this.preparedStatement = preparedStatement; + } + + /** + * Bind the given Avatica values to the prepared statement. + * @param typedValues The parameter values. + */ + public void bind(List typedValues) { + if (preparedStatement.getParameterSchema().getFields().size() != typedValues.size()) { + throw new IllegalStateException( + String.format("Prepared statement has %s parameters, but only received %s", + preparedStatement.getParameterSchema().getFields().size(), + typedValues.size())); + } + + for (int i = 0; i < typedValues.size(); i++) { + final TypedValue param = typedValues.get(i); + final FieldVector vector = parameters.getVector(i); + bindValue(param, vector); + } + + if (!typedValues.isEmpty()) { + parameters.setRowCount(1); + preparedStatement.setParameters(parameters); + } + } + + private void bindValue(TypedValue param, FieldVector vector) { + Object value = param.value; + try { + if (vector instanceof IntVector) { + ((IntVector) vector).setSafe(0, (int) value); + } else if (vector instanceof BigIntVector) { + BigIntVector longVec = (BigIntVector) vector; + if (value instanceof Long) { + longVec.setSafe(0, (long) value); + } else { + longVec.setSafe(0, (int) value); + } + } else if (vector instanceof BitVector) { + ((BitVector) vector).setSafe(0, (int) value); + } else if (vector instanceof Float4Vector) { + ((Float4Vector) vector).setSafe(0, (float) value); + } else if (vector instanceof Float8Vector) { + ((Float8Vector) vector).setSafe(0, (double) value); + } else if (vector instanceof DecimalVector) { + ((DecimalVector) vector).setSafe(0, (BigDecimal) value); + } else if (vector instanceof VarCharVector) { + ((VarCharVector) vector).setSafe(0, new Text((String) value)); + } else if (vector instanceof LargeVarCharVector) { + ((LargeVarCharVector) vector).setSafe(0, new Text((String) value)); + } else if (vector instanceof DateMilliVector) { + String pattern = "yyyy-MM-dd HH:mm:ss.SSS"; + DateTime dateTime = DateTime.parse((String) value, DateTimeFormat.forPattern(pattern)); + + ((DateMilliVector) vector).setSafe(0, dateTime.getMillis()); + } else if (vector instanceof VarBinaryVector) { + ((VarBinaryVector) vector).setSafe(0, (byte[]) value); + } else if (vector instanceof LargeVarBinaryVector) { + ((LargeVarBinaryVector) vector).setSafe(0, (byte[]) value); + } else if (vector instanceof NullVector) { + assert true; + } else { + throw new UnsupportedOperationException( + String.format("Binding to parameter of Arrow type %s", vector.getField().getType())); + } + } catch (ClassCastException e) { + throw new RuntimeException(String.format("Value of type %s is not compatible with Arrow type %s", + param.type, vector.getField().getType())); + } + } + + @Override + public void close() { + parameters.close(); + } +} From 0049dad8703d89c68fef5cce4c70bf9de6c02b43 Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Mon, 23 Oct 2023 18:55:36 +0000 Subject: [PATCH 02/21] Cleanup, fix parameter VSR closing, add basic test --- .../ArrowFlightJdbcFlightStreamResultSet.java | 6 +- ...owFlightJdbcVectorSchemaRootResultSet.java | 10 +--- .../driver/jdbc/ArrowFlightMetaImpl.java | 7 +-- .../driver/jdbc/utils/TypedValueBinder.java | 9 +-- .../ArrowFlightPreparedStatementTest.java | 21 +++++++ .../jdbc/utils/MockFlightSqlProducer.java | 60 ++++++++++++++++++- .../arrow/flight/sql/FlightSqlClient.java | 42 ++++++------- 7 files changed, 111 insertions(+), 44 deletions(-) diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcFlightStreamResultSet.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcFlightStreamResultSet.java index 299e7ccfb4298..690b2d34ea7c0 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcFlightStreamResultSet.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcFlightStreamResultSet.java @@ -153,11 +153,7 @@ private void executeForCurrentFlightStream() throws SQLException { currentVectorSchemaRoot = originalRoot; } - if (schema != null) { - execute(currentVectorSchemaRoot, schema); - } else { - execute(currentVectorSchemaRoot); - } + execute(currentVectorSchemaRoot, schema); } @Override diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcVectorSchemaRootResultSet.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcVectorSchemaRootResultSet.java index 0c6d5e6161ea6..788ae6e8de3ef 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcVectorSchemaRootResultSet.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcVectorSchemaRootResultSet.java @@ -91,17 +91,13 @@ protected AvaticaResultSet execute() throws SQLException { } void execute(final VectorSchemaRoot vectorSchemaRoot) { - final List columns = ConvertUtils.convertArrowFieldsToColumnMetaDataList( - vectorSchemaRoot.getSchema().getFields()); - signature.columns.clear(); - signature.columns.addAll(columns); - - this.vectorSchemaRoot = vectorSchemaRoot; + execute(vectorSchemaRoot, vectorSchemaRoot.getSchema()); execute2(new ArrowFlightJdbcCursor(vectorSchemaRoot), this.signature.columns); } void execute(final VectorSchemaRoot vectorSchemaRoot, final Schema schema) { - final List columns = ConvertUtils.convertArrowFieldsToColumnMetaDataList(schema.getFields()); + Schema currentSchema = schema == null ? vectorSchemaRoot.getSchema() : schema; + final List columns = ConvertUtils.convertArrowFieldsToColumnMetaDataList(currentSchema.getFields()); signature.columns.clear(); signature.columns.addAll(columns); diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java index ec721a9b5dbdc..08682f1695b8d 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java @@ -101,10 +101,9 @@ public ExecuteResult execute(final StatementHandle statementHandle, throw new IllegalStateException("Prepared statement not found: " + statementHandle); } - try (final TypedValueBinder binder = - new TypedValueBinder(preparedStatement, ((ArrowFlightConnection) connection).getBufferAllocator())) { - binder.bind(typedValues); - } + final TypedValueBinder binder = + new TypedValueBinder(preparedStatement, ((ArrowFlightConnection) connection).getBufferAllocator()); + binder.bind(typedValues); if (statementHandle.signature == null) { // Update query diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/TypedValueBinder.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/TypedValueBinder.java index de35f86b1926a..7d12bfa589616 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/TypedValueBinder.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/TypedValueBinder.java @@ -43,8 +43,10 @@ /** * Bind {@link TypedValue}s to a {@link VectorSchemaRoot}. + * + * NOTE: Make sure to close the parameters VectorSchemaRoot once we're done with them. */ -public class TypedValueBinder implements AutoCloseable { +public class TypedValueBinder { private final PreparedStatement preparedStatement; private final VectorSchemaRoot parameters; @@ -121,9 +123,4 @@ private void bindValue(TypedValue param, FieldVector vector) { param.type, vector.getField().getType())); } } - - @Override - public void close() { - parameters.close(); - } } diff --git a/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java b/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java index df2577e955881..2b9bb41c1e95e 100644 --- a/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java +++ b/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java @@ -20,14 +20,20 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.jupiter.api.Assertions.assertEquals; +import java.nio.charset.StandardCharsets; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Collections; import org.apache.arrow.driver.jdbc.utils.CoreMockedSqlProducers; import org.apache.arrow.driver.jdbc.utils.MockFlightSqlProducer; import org.apache.arrow.flight.sql.FlightSqlUtils; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.arrow.vector.types.pojo.Schema; +import org.apache.arrow.vector.util.Text; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -107,4 +113,19 @@ public void testUpdateQuery() throws SQLException { assertEquals(42, updated); } } + + @Test + public void testUpdateQueryWithParameters() throws SQLException { + String query = "Fake update with parameters"; + PRODUCER.addUpdateQuery(query, /*updatedRows*/42); + PRODUCER.addExpectedParameters(query, + new Schema(Collections.singletonList(Field.nullable("", ArrowType.Utf8.INSTANCE))), + Collections.singletonList(Collections.singletonList(new Text("foo".getBytes(StandardCharsets.UTF_8))))); + try (final PreparedStatement stmt = connection.prepareStatement(query)) { + // TODO: make sure this is validated on the server too + stmt.setString(1, "foo"); + int updated = stmt.executeUpdate(); + assertEquals(42, updated); + } + } } diff --git a/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/utils/MockFlightSqlProducer.java b/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/utils/MockFlightSqlProducer.java index 0299eeb46d93b..3752d8e35c400 100644 --- a/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/utils/MockFlightSqlProducer.java +++ b/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/utils/MockFlightSqlProducer.java @@ -34,6 +34,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.UUID; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -75,6 +76,7 @@ import org.apache.arrow.memory.BufferAllocator; import org.apache.arrow.memory.RootAllocator; import org.apache.arrow.util.Preconditions; +import org.apache.arrow.vector.VectorSchemaRoot; import org.apache.arrow.vector.ipc.WriteChannel; import org.apache.arrow.vector.ipc.message.MessageSerializer; import org.apache.arrow.vector.types.pojo.Schema; @@ -97,7 +99,9 @@ public final class MockFlightSqlProducer implements FlightSqlProducer { private final Map>> updateResultProviders = new HashMap<>(); - private SqlInfoBuilder sqlInfoBuilder = new SqlInfoBuilder(); + private final SqlInfoBuilder sqlInfoBuilder = new SqlInfoBuilder(); + private final Map parameterSchemas = new HashMap<>(); + private final Map>> expectedParameterValues = new HashMap<>(); private final Map actionTypeCounter = new HashMap<>(); @@ -192,6 +196,12 @@ void addUpdateQuery(final String sqlCommand, format("Attempted to overwrite pre-existing query: <%s>.", sqlCommand)); } + /** Registers parameters expected to be provided with a prepared statement. */ + public void addExpectedParameters(String query, Schema parameterSchema, List> expectedValues) { + parameterSchemas.put(query, parameterSchema); + expectedParameterValues.put(query, expectedValues); + } + @Override public void createPreparedStatement(final ActionCreatePreparedStatementRequest request, final CallContext callContext, @@ -223,6 +233,13 @@ public void createPreparedStatement(final ActionCreatePreparedStatementRequest r return; } + final Schema parameterSchema = parameterSchemas.get(query); + if (parameterSchema != null) { + final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + MessageSerializer.serialize(new WriteChannel(Channels.newChannel(outputStream)), parameterSchema); + resultBuilder.setParameterSchema(ByteString.copyFrom(outputStream.toByteArray())); + } + listener.onNext(new Result(pack(resultBuilder.build()).toByteArray())); } catch (final Throwable t) { listener.onError(t); @@ -339,6 +356,47 @@ public Runnable acceptPutPreparedStatementUpdate( final String query = Preconditions.checkNotNull( preparedStatements.get(handle), format("No query registered under handle: <%s>.", handle)); + + final List> expectedValues = expectedParameterValues.get(query); + if (expectedValues != null) { + int index = 0; + while (flightStream.next()) { + final VectorSchemaRoot root = flightStream.getRoot(); + for (int i = 0; i < root.getRowCount(); i++) { + if (index >= expectedValues.size()) { + streamListener.onError(CallStatus.INVALID_ARGUMENT + .withDescription("More parameter rows provided than expected") + .toRuntimeException()); + return () -> { }; + } + List expectedRow = expectedValues.get(index++); + if (root.getFieldVectors().size() != expectedRow.size()) { + streamListener.onError(CallStatus.INVALID_ARGUMENT + .withDescription("Parameter count mismatch") + .toRuntimeException()); + return () -> { }; + } + + for (int paramIndex = 0; paramIndex < expectedRow.size(); paramIndex++) { + Object expected = expectedRow.get(paramIndex); + Object actual = root.getVector(paramIndex).getObject(i); + if (!Objects.equals(expected, actual)) { + streamListener.onError(CallStatus.INVALID_ARGUMENT + .withDescription(String.format("Parameter mismatch. Expected: %s Actual: %s", expected, actual)) + .toRuntimeException()); + return () -> { }; + } + } + } + } + if (index < expectedValues.size()) { + streamListener.onError(CallStatus.INVALID_ARGUMENT + .withDescription("Fewer parameter rows provided than expected") + .toRuntimeException()); + return () -> { }; + } + } + return acceptPutStatement( CommandStatementUpdate.newBuilder().setQuery(query).build(), callContext, flightStream, streamListener); diff --git a/java/flight/flight-sql/src/main/java/org/apache/arrow/flight/sql/FlightSqlClient.java b/java/flight/flight-sql/src/main/java/org/apache/arrow/flight/sql/FlightSqlClient.java index e72354513013e..82fc785940760 100644 --- a/java/flight/flight-sql/src/main/java/org/apache/arrow/flight/sql/FlightSqlClient.java +++ b/java/flight/flight-sql/src/main/java/org/apache/arrow/flight/sql/FlightSqlClient.java @@ -951,12 +951,11 @@ public static class PreparedStatement implements AutoCloseable { * {@code PreparedStatement} setters. */ public void setParameters(final VectorSchemaRoot parameterBindingRoot) { - if (this.parameterBindingRoot != null) { - if (this.parameterBindingRoot.equals(parameterBindingRoot)) { - return; - } - this.parameterBindingRoot.close(); + if (parameterBindingRoot.equals(this.parameterBindingRoot)) { + // Nothing to do if we're attempting to set the same parameters again. + return; } + clearParameters(); this.parameterBindingRoot = parameterBindingRoot; } @@ -1038,19 +1037,25 @@ public FlightInfo execute(final CallOption... options) { .toByteArray()); if (parameterBindingRoot != null && parameterBindingRoot.getRowCount() > 0) { - final SyncPutListener putListener = new SyncPutListener(); - - FlightClient.ClientStreamListener listener = - client.startPut(descriptor, parameterBindingRoot, putListener, options); - - listener.putNext(); - listener.completed(); - listener.getResult(); + putParameters(descriptor, options); } return client.getInfo(descriptor, options); } + private SyncPutListener putParameters(FlightDescriptor descriptor, CallOption... options) { + final SyncPutListener putListener = new SyncPutListener(); + + FlightClient.ClientStreamListener listener = + client.startPut(descriptor, parameterBindingRoot, putListener, options); + + listener.putNext(); + listener.completed(); + listener.getResult(); + + return putListener; + } + /** * Checks whether this client is open. * @@ -1074,11 +1079,8 @@ public long executeUpdate(final CallOption... options) { .build()) .toByteArray()); setParameters(parameterBindingRoot == null ? VectorSchemaRoot.of() : parameterBindingRoot); - final SyncPutListener putListener = new SyncPutListener(); - final FlightClient.ClientStreamListener listener = - client.startPut(descriptor, parameterBindingRoot, putListener, options); - listener.putNext(); - listener.completed(); + SyncPutListener putListener = putParameters(descriptor, options); + try { final PutResult read = putListener.read(); try (final ArrowBuf metadata = read.getApplicationMetadata()) { @@ -1112,9 +1114,7 @@ public void close(final CallOption... options) { final Iterator closePreparedStatementResults = client.doAction(action, options); closePreparedStatementResults.forEachRemaining(result -> { }); - if (parameterBindingRoot != null) { - parameterBindingRoot.close(); - } + clearParameters(); } @Override From 4d0ce8fb0d3ee347963417edb1dbe9aad3196b07 Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Mon, 23 Oct 2023 19:29:23 +0000 Subject: [PATCH 03/21] fix docstring --- .../java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java index 08682f1695b8d..66bcffaa95918 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java @@ -56,7 +56,7 @@ public ArrowFlightMetaImpl(final AvaticaConnection connection) { } /** - * Construct a signature with only the SQL query. Column metadata and parameters must be filled out elsewhere. + * Construct a signature. */ static Signature newSignature(final String sql, Schema resultSetSchema, Schema parameterSchema) { List columnMetaData = resultSetSchema == null ? From d2cb6672dafa5e195df8003a790958a08df1fc80 Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Mon, 23 Oct 2023 21:31:30 +0000 Subject: [PATCH 04/21] Add test for binding query params --- .../ArrowFlightPreparedStatementTest.java | 15 ++++++ .../jdbc/utils/MockFlightSqlProducer.java | 49 +++++++++++++------ 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java b/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java index 2b9bb41c1e95e..e536a404f2962 100644 --- a/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java +++ b/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java @@ -79,6 +79,21 @@ public void testSimpleQueryNoParameterBinding() throws SQLException { } } + @Test + public void testQueryWithParameterBinding() throws SQLException { + final String query = CoreMockedSqlProducers.LEGACY_REGULAR_SQL_CMD; + PRODUCER.addExpectedParameters(query, + new Schema(Collections.singletonList(Field.nullable("", ArrowType.Utf8.INSTANCE))), + Collections.singletonList(Collections.singletonList(new Text("foo".getBytes(StandardCharsets.UTF_8))))); + try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) { + preparedStatement.setString(1, "foo"); + try (final ResultSet resultSet = preparedStatement.executeQuery()) { + CoreMockedSqlProducers.assertLegacyRegularSqlResultSet(resultSet, collector); + } + } + } + + @Test @Ignore("https://github.com/apache/arrow/issues/34741: flaky test") public void testPreparedStatementExecutionOnce() throws SQLException { diff --git a/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/utils/MockFlightSqlProducer.java b/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/utils/MockFlightSqlProducer.java index 3752d8e35c400..75a7396931c8e 100644 --- a/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/utils/MockFlightSqlProducer.java +++ b/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/utils/MockFlightSqlProducer.java @@ -347,16 +347,9 @@ public Runnable acceptPutStatement(final CommandStatementUpdate commandStatement }; } - @Override - public Runnable acceptPutPreparedStatementUpdate( - final CommandPreparedStatementUpdate commandPreparedStatementUpdate, - final CallContext callContext, final FlightStream flightStream, - final StreamListener streamListener) { - final ByteString handle = commandPreparedStatementUpdate.getPreparedStatementHandle(); - final String query = Preconditions.checkNotNull( - preparedStatements.get(handle), - format("No query registered under handle: <%s>.", handle)); - + private boolean validateParameters(String query, + FlightStream flightStream, + StreamListener streamListener) { final List> expectedValues = expectedParameterValues.get(query); if (expectedValues != null) { int index = 0; @@ -367,14 +360,14 @@ public Runnable acceptPutPreparedStatementUpdate( streamListener.onError(CallStatus.INVALID_ARGUMENT .withDescription("More parameter rows provided than expected") .toRuntimeException()); - return () -> { }; + return true; } List expectedRow = expectedValues.get(index++); if (root.getFieldVectors().size() != expectedRow.size()) { streamListener.onError(CallStatus.INVALID_ARGUMENT .withDescription("Parameter count mismatch") .toRuntimeException()); - return () -> { }; + return true; } for (int paramIndex = 0; paramIndex < expectedRow.size(); paramIndex++) { @@ -384,7 +377,7 @@ public Runnable acceptPutPreparedStatementUpdate( streamListener.onError(CallStatus.INVALID_ARGUMENT .withDescription(String.format("Parameter mismatch. Expected: %s Actual: %s", expected, actual)) .toRuntimeException()); - return () -> { }; + return true; } } } @@ -393,9 +386,25 @@ public Runnable acceptPutPreparedStatementUpdate( streamListener.onError(CallStatus.INVALID_ARGUMENT .withDescription("Fewer parameter rows provided than expected") .toRuntimeException()); - return () -> { }; + return true; } } + return false; + } + + @Override + public Runnable acceptPutPreparedStatementUpdate( + final CommandPreparedStatementUpdate commandPreparedStatementUpdate, + final CallContext callContext, final FlightStream flightStream, + final StreamListener streamListener) { + final ByteString handle = commandPreparedStatementUpdate.getPreparedStatementHandle(); + final String query = Preconditions.checkNotNull( + preparedStatements.get(handle), + format("No query registered under handle: <%s>.", handle)); + + if (validateParameters(query, flightStream, streamListener)) { + return () -> { }; + } return acceptPutStatement( CommandStatementUpdate.newBuilder().setQuery(query).build(), callContext, flightStream, @@ -407,8 +416,16 @@ public Runnable acceptPutPreparedStatementQuery( final CommandPreparedStatementQuery commandPreparedStatementQuery, final CallContext callContext, final FlightStream flightStream, final StreamListener streamListener) { - // TODO Implement this method. - throw CallStatus.UNIMPLEMENTED.toRuntimeException(); + final ByteString handle = commandPreparedStatementQuery.getPreparedStatementHandle(); + final String query = Preconditions.checkNotNull( + preparedStatements.get(handle), + format("No query registered under handle: <%s>.", handle)); + + if (validateParameters(query, flightStream, streamListener)) { + return () -> { }; + } + + return streamListener::onCompleted; } @Override From cad225a1cac35713bb660cba0664738c4376edef Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Mon, 23 Oct 2023 22:04:29 +0000 Subject: [PATCH 05/21] Fix test for query params --- .../ArrowFlightPreparedStatementTest.java | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java b/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java index e536a404f2962..4ead04d2a5c38 100644 --- a/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java +++ b/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java @@ -30,10 +30,16 @@ import org.apache.arrow.driver.jdbc.utils.CoreMockedSqlProducers; import org.apache.arrow.driver.jdbc.utils.MockFlightSqlProducer; import org.apache.arrow.flight.sql.FlightSqlUtils; +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.apache.arrow.vector.IntVector; +import org.apache.arrow.vector.VectorSchemaRoot; +import org.apache.arrow.vector.types.Types; import org.apache.arrow.vector.types.pojo.ArrowType; import org.apache.arrow.vector.types.pojo.Field; import org.apache.arrow.vector.types.pojo.Schema; import org.apache.arrow.vector.util.Text; + import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -81,14 +87,32 @@ public void testSimpleQueryNoParameterBinding() throws SQLException { @Test public void testQueryWithParameterBinding() throws SQLException { - final String query = CoreMockedSqlProducers.LEGACY_REGULAR_SQL_CMD; + final String query = "Fake query with parameters"; + final Schema schema = new Schema(Collections.singletonList(Field.nullable("", Types.MinorType.INT.getType()))); + PRODUCER.addSelectQuery(query, schema, + Collections.singletonList(listener -> { + try (final BufferAllocator allocator = new RootAllocator(Long.MAX_VALUE); + final VectorSchemaRoot root = VectorSchemaRoot.create(schema, + allocator)) { + ((IntVector) root.getVector(0)).setSafe(0, 10); + root.setRowCount(1); + listener.start(root); + listener.putNext(); + } catch (final Throwable throwable) { + listener.error(throwable); + } finally { + listener.completed(); + } + })); + PRODUCER.addExpectedParameters(query, new Schema(Collections.singletonList(Field.nullable("", ArrowType.Utf8.INSTANCE))), Collections.singletonList(Collections.singletonList(new Text("foo".getBytes(StandardCharsets.UTF_8))))); try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) { preparedStatement.setString(1, "foo"); try (final ResultSet resultSet = preparedStatement.executeQuery()) { - CoreMockedSqlProducers.assertLegacyRegularSqlResultSet(resultSet, collector); + resultSet.next(); + assert true; } } } From 3bb139ba6c6c1b7d3f4725cc03b1596f6f6c05e8 Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Mon, 23 Oct 2023 22:06:02 +0000 Subject: [PATCH 06/21] . --- .../arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java b/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java index 4ead04d2a5c38..2f3f27da961e8 100644 --- a/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java +++ b/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java @@ -39,7 +39,6 @@ import org.apache.arrow.vector.types.pojo.Field; import org.apache.arrow.vector.types.pojo.Schema; import org.apache.arrow.vector.util.Text; - import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; From a30f0afdea0902dba61e05230d26586fc3c9bd04 Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Wed, 25 Oct 2023 05:44:55 +0000 Subject: [PATCH 07/21] modify for consistency --- .../org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java | 4 ++-- .../java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java index 8e9384e577373..6dd9e165d79d7 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java @@ -31,8 +31,8 @@ * Helper class to convert Arrow types to JDBC required values. */ class ArrowToJdbcUtils { - static boolean isSigned(ArrowType.ArrowTypeID type) { - switch (type) { + static boolean isSigned(ArrowType type) { + switch (type.getTypeID()) { case Int: case FloatingPoint: case Decimal: diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java index d6bb8678e0d80..45732cedf7365 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java @@ -123,7 +123,7 @@ public static void setOnColumnMetaDataBuilder(final Builder builder, */ public static List convertArrowFieldsToAvaticaParameters(final List fields) { return fields.stream().map(field -> { - final boolean signed = ArrowToJdbcUtils.isSigned(field.getType().getTypeID()); + final boolean signed = ArrowToJdbcUtils.isSigned(field.getType()); final int precision = 0; // Would have to know about the actual number final int scale = 0; // According to https://www.postgresql.org/docs/current/datatype-numeric.html final int type = ArrowToJdbcUtils.toJdbcType(field.getType()); From 30763aeed6cbb150c60d75e444ac3e6312a1d0d5 Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Wed, 25 Oct 2023 18:35:52 +0000 Subject: [PATCH 08/21] Address ArrowToJdbc type conversion feedback --- .../driver/jdbc/utils/ArrowToJdbcUtils.java | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java index 6dd9e165d79d7..f3abd3e98cdb0 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java @@ -25,6 +25,7 @@ import java.util.ArrayList; import java.util.HashMap; +import org.apache.arrow.vector.types.FloatingPointPrecision; import org.apache.arrow.vector.types.pojo.ArrowType; /** @@ -34,6 +35,7 @@ class ArrowToJdbcUtils { static boolean isSigned(ArrowType type) { switch (type.getTypeID()) { case Int: + return ((ArrowType.Int) type).getIsSigned(); case FloatingPoint: case Decimal: case Interval: @@ -55,9 +57,32 @@ static int toJdbcType(ArrowType type) { case FixedSizeList: return Types.ARRAY; case Int: - return ((ArrowType.Int) type).getBitWidth() == 64 ? Types.BIGINT : Types.INTEGER; + switch(((ArrowType.Int) type).getBitWidth()) { + case 64: + return Types.BIGINT; + case 32: + return Types.INTEGER; + case 16: + return Types.SMALLINT; + case 8: + return Types.TINYINT; + } case FloatingPoint: - return Types.FLOAT; + /* + * These are a bit confusing. The following are equivalent: + * + * Highest precision: + * - JDBC REAL + * - Arrow DOUBLE + * + * Lower precision: + * - JDBC FLOAT + * - JDBC DOUBLE + * - Arrow SINGLE + * - Arrow HALF + */ + return ((ArrowType.FloatingPoint) type).getPrecision() == FloatingPointPrecision.DOUBLE ? + Types.REAL : Types.DOUBLE; case Utf8: case LargeUtf8: return Types.VARCHAR; @@ -75,9 +100,9 @@ static int toJdbcType(ArrowType type) { case Time: return Types.TIME; case Timestamp: + return Types.TIMESTAMP; case Interval: case Duration: - return Types.TIMESTAMP; default: return Types.OTHER; } @@ -96,7 +121,8 @@ static String getClassName(ArrowType type) { return ((ArrowType.Int) type).getBitWidth() == 64 ? long.class.getCanonicalName() : int.class.getCanonicalName(); case FloatingPoint: - return float.class.getCanonicalName(); + return ((ArrowType.FloatingPoint) type).getPrecision() == FloatingPointPrecision.DOUBLE ? + double.class.getCanonicalName() : float.class.getCanonicalName(); case Utf8: case LargeUtf8: return String.class.getCanonicalName(); From 0942a3986958c743db89d5281bc8f0f523a16cd6 Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Wed, 25 Oct 2023 18:50:12 +0000 Subject: [PATCH 09/21] . --- .../org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java index f3abd3e98cdb0..c5c4cfdd69244 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java @@ -57,7 +57,7 @@ static int toJdbcType(ArrowType type) { case FixedSizeList: return Types.ARRAY; case Int: - switch(((ArrowType.Int) type).getBitWidth()) { + switch (((ArrowType.Int) type).getBitWidth()) { case 64: return Types.BIGINT; case 32: @@ -66,6 +66,9 @@ static int toJdbcType(ArrowType type) { return Types.SMALLINT; case 8: return Types.TINYINT; + default: + // FIXME: Does this ever even happen? + return Types.OTHER; } case FloatingPoint: /* From f4210809bfe224b95bd0ef63af0de741c676aae7 Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Mon, 30 Oct 2023 05:29:28 +0000 Subject: [PATCH 10/21] Refactor param converter logic --- ...owFlightJdbcVectorSchemaRootResultSet.java | 2 +- .../driver/jdbc/ArrowFlightMetaImpl.java | 11 +- .../driver/jdbc/ArrowFlightStatement.java | 2 +- .../ArrowFieldToAvaticaParameter.java | 162 ++++++++++++++++ .../converter/AvaticaParameterConverter.java | 28 +++ .../{utils => converter}/ConvertUtils.java | 14 +- .../impl/BaseAvaticaParameterConverter.java | 38 ++++ .../impl/BinaryAvaticaParameterConverter.java | 46 +++++ .../impl/BoolAvaticaParameterConverter.java | 46 +++++ .../impl/DateAvaticaParameterConverter.java | 51 +++++ .../DecimalAvaticaParameterConverter.java | 48 +++++ .../DurationAvaticaParameterConverter.java | 40 ++++ ...edSizeBinaryAvaticaParameterConverter.java | 46 +++++ ...loatingPointAvaticaParameterConverter.java | 50 +++++ .../impl/IntAvaticaParameterConverter.java | 86 +++++++++ .../IntervalAvaticaParameterConverter.java | 46 +++++ .../LargeBinaryAvaticaParameterConverter.java | 46 +++++ .../LargeUtf8AvaticaParameterConverter.java | 47 +++++ .../impl/NullAvaticaParameterConverter.java | 46 +++++ .../impl/TimeAvaticaParameterConverter.java | 58 ++++++ .../TimestampAvaticaParameterConverter.java | 75 ++++++++ .../impl/Utf8AvaticaParameterConverter.java | 47 +++++ .../driver/jdbc/utils/ArrowToJdbcUtils.java | 152 --------------- .../jdbc/utils/AvaticaParameterBinder.java | 65 +++++++ .../driver/jdbc/utils/TypedValueBinder.java | 126 ------------ .../jdbc/utils/TypedValueVectorBinder.java | 180 ++++++++++++++++++ .../driver/jdbc/utils/ConvertUtilsTest.java | 1 + 27 files changed, 1262 insertions(+), 297 deletions(-) create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/ArrowFieldToAvaticaParameter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/AvaticaParameterConverter.java rename java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/{utils => converter}/ConvertUtils.java (85%) create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BaseAvaticaParameterConverter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BinaryAvaticaParameterConverter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BoolAvaticaParameterConverter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DateAvaticaParameterConverter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DecimalAvaticaParameterConverter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DurationAvaticaParameterConverter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FixedSizeBinaryAvaticaParameterConverter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FloatingPointAvaticaParameterConverter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntAvaticaParameterConverter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntervalAvaticaParameterConverter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeBinaryAvaticaParameterConverter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeUtf8AvaticaParameterConverter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/NullAvaticaParameterConverter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimeAvaticaParameterConverter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimestampAvaticaParameterConverter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/Utf8AvaticaParameterConverter.java delete mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java delete mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/TypedValueBinder.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/TypedValueVectorBinder.java diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcVectorSchemaRootResultSet.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcVectorSchemaRootResultSet.java index 788ae6e8de3ef..99402636e799b 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcVectorSchemaRootResultSet.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcVectorSchemaRootResultSet.java @@ -26,7 +26,7 @@ import java.util.Set; import java.util.TimeZone; -import org.apache.arrow.driver.jdbc.utils.ConvertUtils; +import org.apache.arrow.driver.jdbc.converter.ConvertUtils; import org.apache.arrow.util.AutoCloseables; import org.apache.arrow.vector.VectorSchemaRoot; import org.apache.arrow.vector.types.pojo.Schema; diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java index 66bcffaa95918..91b942daf2534 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java @@ -27,8 +27,8 @@ import java.util.concurrent.ConcurrentHashMap; import org.apache.arrow.driver.jdbc.client.ArrowFlightSqlClientHandler.PreparedStatement; -import org.apache.arrow.driver.jdbc.utils.ConvertUtils; -import org.apache.arrow.driver.jdbc.utils.TypedValueBinder; +import org.apache.arrow.driver.jdbc.converter.ConvertUtils; +import org.apache.arrow.driver.jdbc.utils.AvaticaParameterBinder; import org.apache.arrow.util.Preconditions; import org.apache.arrow.vector.types.pojo.Schema; import org.apache.calcite.avatica.AvaticaConnection; @@ -94,15 +94,14 @@ public ExecuteResult execute(final StatementHandle statementHandle, final List typedValues, final long maxRowCount) { Preconditions.checkArgument(connection.id.equals(statementHandle.connectionId), "Connection IDs are not consistent"); - final StatementHandleKey key = new StatementHandleKey(statementHandle); - PreparedStatement preparedStatement = statementHandlePreparedStatementMap.get(key); + PreparedStatement preparedStatement = getPreparedStatement(statementHandle); if (preparedStatement == null) { throw new IllegalStateException("Prepared statement not found: " + statementHandle); } - final TypedValueBinder binder = - new TypedValueBinder(preparedStatement, ((ArrowFlightConnection) connection).getBufferAllocator()); + final AvaticaParameterBinder binder = + new AvaticaParameterBinder(preparedStatement, ((ArrowFlightConnection) connection).getBufferAllocator()); binder.bind(typedValues); if (statementHandle.signature == null) { diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightStatement.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightStatement.java index 5bc7c2ab9b4f8..a73c5f9d4bb9d 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightStatement.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightStatement.java @@ -20,7 +20,7 @@ import java.sql.SQLException; import org.apache.arrow.driver.jdbc.client.ArrowFlightSqlClientHandler.PreparedStatement; -import org.apache.arrow.driver.jdbc.utils.ConvertUtils; +import org.apache.arrow.driver.jdbc.converter.ConvertUtils; import org.apache.arrow.flight.FlightInfo; import org.apache.arrow.vector.types.pojo.Schema; import org.apache.calcite.avatica.AvaticaStatement; diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/ArrowFieldToAvaticaParameter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/ArrowFieldToAvaticaParameter.java new file mode 100644 index 0000000000000..86a1778805049 --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/ArrowFieldToAvaticaParameter.java @@ -0,0 +1,162 @@ +/* + * 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.driver.jdbc.converter; + +import org.apache.arrow.driver.jdbc.converter.impl.BinaryAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.BoolAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.DateAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.DecimalAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.DurationAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.FixedSizeBinaryAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.FloatingPointAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.IntAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.IntervalAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.LargeBinaryAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.LargeUtf8AvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.NullAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.TimeAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.TimestampAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.Utf8AvaticaParameterConverter; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; + +/** + * Create a + */ +public class ArrowFieldToAvaticaParameter { + /** + * Bind a TypedValue to the given index on the FieldVctor. + */ + static AvaticaParameter convert(Field field) { + return field.getType().accept(new ConverterVisitor(field)); + } + + private static class ConverterVisitor implements ArrowType.ArrowTypeVisitor { + private final Field field; + + private ConverterVisitor(Field field) { + this.field = field; + } + + @Override + public AvaticaParameter visit(ArrowType.Null type) { + return new NullAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.Struct type) { + throw new UnsupportedOperationException(); + } + + @Override + public AvaticaParameter visit(ArrowType.List type) { + throw new UnsupportedOperationException(); + } + + @Override + public AvaticaParameter visit(ArrowType.LargeList type) { + throw new UnsupportedOperationException(); + } + + @Override + public AvaticaParameter visit(ArrowType.FixedSizeList type) { + throw new UnsupportedOperationException(); + } + + @Override + public AvaticaParameter visit(ArrowType.Union type) { + throw new UnsupportedOperationException(); + } + + @Override + public AvaticaParameter visit(ArrowType.Map type) { + throw new UnsupportedOperationException(); + } + + @Override + public AvaticaParameter visit(ArrowType.Int type) { + return new IntAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.FloatingPoint type) { + return new FloatingPointAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.Utf8 type) { + return new Utf8AvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.LargeUtf8 type) { + return new LargeUtf8AvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.Binary type) { + return new BinaryAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.LargeBinary type) { + return new LargeBinaryAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.FixedSizeBinary type) { + return new FixedSizeBinaryAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.Bool type) { + return new BoolAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.Decimal type) { + return new DecimalAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.Date type) { + return new DateAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.Time type) { + return new TimeAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.Timestamp type) { + return new TimestampAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.Interval type) { + return new IntervalAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.Duration type) { + return new DurationAvaticaParameterConverter(type).createParameter(field); + } + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/AvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/AvaticaParameterConverter.java new file mode 100644 index 0000000000000..366575ad87434 --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/AvaticaParameterConverter.java @@ -0,0 +1,28 @@ +/* + * 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.driver.jdbc.converter; + +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +public interface AvaticaParameterConverter { + boolean setParameter(FieldVector vector, TypedValue typedValue, int index); + AvaticaParameter createParameter(Field field); +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/ConvertUtils.java similarity index 85% rename from java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java rename to java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/ConvertUtils.java index 45732cedf7365..dca4e3ec254ad 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/ConvertUtils.java @@ -15,13 +15,14 @@ * limitations under the License. */ -package org.apache.arrow.driver.jdbc.utils; +package org.apache.arrow.driver.jdbc.converter; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.apache.arrow.driver.jdbc.utils.SqlTypes; import org.apache.arrow.flight.sql.FlightSqlColumnMetadata; import org.apache.arrow.vector.types.pojo.ArrowType; import org.apache.arrow.vector.types.pojo.Field; @@ -122,15 +123,6 @@ public static void setOnColumnMetaDataBuilder(final Builder builder, * @return list of {@link AvaticaParameter}. */ public static List convertArrowFieldsToAvaticaParameters(final List fields) { - return fields.stream().map(field -> { - final boolean signed = ArrowToJdbcUtils.isSigned(field.getType()); - final int precision = 0; // Would have to know about the actual number - final int scale = 0; // According to https://www.postgresql.org/docs/current/datatype-numeric.html - final int type = ArrowToJdbcUtils.toJdbcType(field.getType()); - final String typeName = field.getType().toString(); - final String clazz = ArrowToJdbcUtils.getClassName(field.getType()); - final String name = field.getName(); - return new AvaticaParameter(signed, precision, scale, type, typeName, clazz, name); - }).collect(Collectors.toList()); + return fields.stream().map(ArrowFieldToAvaticaParameter::convert).collect(Collectors.toList()); } } diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BaseAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BaseAvaticaParameterConverter.java new file mode 100644 index 0000000000000..30c380f8a6642 --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BaseAvaticaParameterConverter.java @@ -0,0 +1,38 @@ +/* + * 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.driver.jdbc.converter.impl; + +import org.apache.arrow.driver.jdbc.converter.AvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.utils.SqlTypes; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.SqlType; + +abstract class BaseAvaticaParameterConverter implements AvaticaParameterConverter { + protected AvaticaParameter createParameter(Field field, boolean signed) { + final String name = field.getName(); + final ArrowType arrowType = field.getType(); + final String typeName = arrowType.toString(); + final int precision = 0; // Would have to know about the actual number + final int scale = 0; // According to https://www.postgresql.org/docs/current/datatype-numeric.html + final int jdbcType = SqlTypes.getSqlTypeIdFromArrowType(arrowType); + final String className = SqlType.valueOf(jdbcType).clazz.getCanonicalName(); + return new AvaticaParameter(signed, precision, scale, jdbcType, typeName, className, name); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BinaryAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BinaryAvaticaParameterConverter.java new file mode 100644 index 0000000000000..ef2f1cfa3c662 --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BinaryAvaticaParameterConverter.java @@ -0,0 +1,46 @@ +/* + * 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.driver.jdbc.converter.impl; + +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.VarBinaryVector; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +public class BinaryAvaticaParameterConverter extends BaseAvaticaParameterConverter { + + public BinaryAvaticaParameterConverter(ArrowType.Binary type) { + } + + @Override + public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + Object value = typedValue.toLocal(); + if (vector instanceof VarBinaryVector) { + ((VarBinaryVector) vector).setSafe(index, (byte[]) value); + return true; + } + return false; + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, false); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BoolAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BoolAvaticaParameterConverter.java new file mode 100644 index 0000000000000..74b01ddef4120 --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BoolAvaticaParameterConverter.java @@ -0,0 +1,46 @@ +/* + * 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.driver.jdbc.converter.impl; + +import org.apache.arrow.vector.BitVector; +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +public class BoolAvaticaParameterConverter extends BaseAvaticaParameterConverter { + + public BoolAvaticaParameterConverter(ArrowType.Bool type) { + } + + @Override + public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + Object value = typedValue.toLocal(); + if (vector instanceof BitVector) { + ((BitVector) vector).setSafe(index, (int) value); + return true; + } + return false; + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, false); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DateAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DateAvaticaParameterConverter.java new file mode 100644 index 0000000000000..dc0c5a6276173 --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DateAvaticaParameterConverter.java @@ -0,0 +1,51 @@ +/* + * 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.driver.jdbc.converter.impl; + +import org.apache.arrow.vector.DateDayVector; +import org.apache.arrow.vector.DateMilliVector; +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +public class DateAvaticaParameterConverter extends BaseAvaticaParameterConverter { + + public DateAvaticaParameterConverter(ArrowType.Date type) { + } + + @Override + public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + Object value = typedValue.toLocal(); + if (vector instanceof DateMilliVector) { + ((DateMilliVector) vector).setSafe(index, (int) value); + return true; + } else if (vector instanceof DateDayVector) { + ((DateDayVector) vector).setSafe(index, (int) value); + return true; + } + return false; + + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, false); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DecimalAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DecimalAvaticaParameterConverter.java new file mode 100644 index 0000000000000..114d18c15dde5 --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DecimalAvaticaParameterConverter.java @@ -0,0 +1,48 @@ +/* + * 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.driver.jdbc.converter.impl; + +import java.math.BigDecimal; + +import org.apache.arrow.vector.DecimalVector; +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +public class DecimalAvaticaParameterConverter extends BaseAvaticaParameterConverter { + + public DecimalAvaticaParameterConverter(ArrowType.Decimal type) { + } + + @Override + public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + Object value = typedValue.toLocal(); + if (vector instanceof DecimalVector) { + ((DecimalVector) vector).setSafe(index, (BigDecimal) value); + return true; + } + return false; + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, true); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DurationAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DurationAvaticaParameterConverter.java new file mode 100644 index 0000000000000..4f89b86f51901 --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DurationAvaticaParameterConverter.java @@ -0,0 +1,40 @@ +/* + * 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.driver.jdbc.converter.impl; + +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +public class DurationAvaticaParameterConverter extends BaseAvaticaParameterConverter { + + public DurationAvaticaParameterConverter(ArrowType.Duration type) { + } + + @Override + public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + return false; + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, false); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FixedSizeBinaryAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FixedSizeBinaryAvaticaParameterConverter.java new file mode 100644 index 0000000000000..46b776b3fb8b3 --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FixedSizeBinaryAvaticaParameterConverter.java @@ -0,0 +1,46 @@ +/* + * 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.driver.jdbc.converter.impl; + +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.FixedSizeBinaryVector; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +public class FixedSizeBinaryAvaticaParameterConverter extends BaseAvaticaParameterConverter { + + public FixedSizeBinaryAvaticaParameterConverter(ArrowType.FixedSizeBinary type) { + } + + @Override + public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + Object value = typedValue.toLocal(); + if (vector instanceof FixedSizeBinaryVector) { + ((FixedSizeBinaryVector) vector).setSafe(index, (byte[]) value); + return true; + } + return false; + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, false); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FloatingPointAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FloatingPointAvaticaParameterConverter.java new file mode 100644 index 0000000000000..7352aa810f9f3 --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FloatingPointAvaticaParameterConverter.java @@ -0,0 +1,50 @@ +/* + * 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.driver.jdbc.converter.impl; + +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.Float4Vector; +import org.apache.arrow.vector.Float8Vector; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +public class FloatingPointAvaticaParameterConverter extends BaseAvaticaParameterConverter { + + public FloatingPointAvaticaParameterConverter(ArrowType.FloatingPoint type) { + } + + @Override + public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + Object value = typedValue.toLocal(); + if (vector instanceof Float4Vector) { + ((Float4Vector) vector).setSafe(index, (float) value); + return true; + } else if (vector instanceof Float8Vector) { + ((Float8Vector) vector).setSafe(index, (double) value); + return true; + } + return false; + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, true); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntAvaticaParameterConverter.java new file mode 100644 index 0000000000000..21b79ee0c5221 --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntAvaticaParameterConverter.java @@ -0,0 +1,86 @@ +/* + * 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.driver.jdbc.converter.impl; + +import org.apache.arrow.vector.BigIntVector; +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.IntVector; +import org.apache.arrow.vector.SmallIntVector; +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.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +public class IntAvaticaParameterConverter extends BaseAvaticaParameterConverter { + final private ArrowType.Int type; + + public IntAvaticaParameterConverter(ArrowType.Int type) { + this.type = type; + } + + @Override + public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + Object value = typedValue.toLocal(); + if (vector instanceof TinyIntVector) { + ((TinyIntVector) vector).setSafe(index, (int) value); + return true; + } else if (vector instanceof SmallIntVector) { + ((SmallIntVector) vector).setSafe(index, (int) value); + return true; + } else if (vector instanceof IntVector) { + ((IntVector) vector).setSafe(index, (int) value); + return true; + } else if (vector instanceof BigIntVector) { + BigIntVector longVec = (BigIntVector) vector; + if (value instanceof Long) { + longVec.setSafe(index, (long) value); + } else { + longVec.setSafe(index, (int) value); + } + return true; + } else if (vector instanceof UInt1Vector) { + ((UInt1Vector) vector).setSafe(index, (int) value); + return true; + } else if (vector instanceof UInt2Vector) { + ((UInt2Vector) vector).setSafe(index, (int) value); + return true; + } else if (vector instanceof UInt4Vector) { + ((UInt4Vector) vector).setSafe(index, (int) value); + return true; + } else if (vector instanceof UInt8Vector) { + UInt8Vector longVec = (UInt8Vector) vector; + if (value instanceof Long) { + longVec.setSafe(index, (long) value); + } else { + longVec.setSafe(index, (int) value); + } + return true; + } + return false; + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, type.getIsSigned()); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntervalAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntervalAvaticaParameterConverter.java new file mode 100644 index 0000000000000..68ada9aad9413 --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntervalAvaticaParameterConverter.java @@ -0,0 +1,46 @@ +/* + * 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.driver.jdbc.converter.impl; + +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +public class IntervalAvaticaParameterConverter extends BaseAvaticaParameterConverter { + + public IntervalAvaticaParameterConverter(ArrowType.Interval type) { + } + + @Override + public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { +// Object value = typedValue.toLocal(); +// if (vector instanceof IntervalDayVector) { +// ((IntervalDayVector) vector).setSafe(index, () value); +// } else if (vector instanceof IntervalYearVector) { +// ((IntervalYearVector) vector).setSafe(index, () value); +// } + return false; + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, false); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeBinaryAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeBinaryAvaticaParameterConverter.java new file mode 100644 index 0000000000000..c55da41ab4403 --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeBinaryAvaticaParameterConverter.java @@ -0,0 +1,46 @@ +/* + * 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.driver.jdbc.converter.impl; + +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.LargeVarBinaryVector; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +public class LargeBinaryAvaticaParameterConverter extends BaseAvaticaParameterConverter { + + public LargeBinaryAvaticaParameterConverter(ArrowType.LargeBinary type) { + } + + @Override + public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + Object value = typedValue.toLocal(); + if (vector instanceof LargeVarBinaryVector) { + ((LargeVarBinaryVector) vector).setSafe(index, (byte[]) value); + return true; + } + return false; + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, false); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeUtf8AvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeUtf8AvaticaParameterConverter.java new file mode 100644 index 0000000000000..783bff2f8ad55 --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeUtf8AvaticaParameterConverter.java @@ -0,0 +1,47 @@ +/* + * 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.driver.jdbc.converter.impl; + +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.LargeVarCharVector; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.arrow.vector.util.Text; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +public class LargeUtf8AvaticaParameterConverter extends BaseAvaticaParameterConverter { + + public LargeUtf8AvaticaParameterConverter(ArrowType.LargeUtf8 type) { + } + + @Override + public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + Object value = typedValue.toLocal(); + if (vector instanceof LargeVarCharVector) { + ((LargeVarCharVector) vector).setSafe(index, new Text((String) value)); + return true; + } + return false; + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, false); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/NullAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/NullAvaticaParameterConverter.java new file mode 100644 index 0000000000000..9d3ce0c6d1fae --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/NullAvaticaParameterConverter.java @@ -0,0 +1,46 @@ +/* + * 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.driver.jdbc.converter.impl; + +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.NullVector; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +public class NullAvaticaParameterConverter extends BaseAvaticaParameterConverter { + + public NullAvaticaParameterConverter(ArrowType.Null type) { + } + + @Override + public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + Object value = typedValue.toLocal(); + if (vector instanceof NullVector) { + if (value != null) throw new RuntimeException("Can't set non-null value on NullVector"); + vector.setNull(index); + } + return false; + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, false); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimeAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimeAvaticaParameterConverter.java new file mode 100644 index 0000000000000..befe0b932c92d --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimeAvaticaParameterConverter.java @@ -0,0 +1,58 @@ +/* + * 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.driver.jdbc.converter.impl; + +import org.apache.arrow.vector.FieldVector; +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.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +public class TimeAvaticaParameterConverter extends BaseAvaticaParameterConverter { + + public TimeAvaticaParameterConverter(ArrowType.Time type) { + } + + @Override + public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + int value = (int) typedValue.toLocal(); + if (vector instanceof TimeMicroVector) { + ((TimeMicroVector) vector).setSafe(index, value); + return true; + } else if (vector instanceof TimeMilliVector) { + ((TimeMilliVector) vector).setSafe(index, value); + return true; + } else if (vector instanceof TimeNanoVector) { + ((TimeNanoVector) vector).setSafe(index, value); + return true; + } else if (vector instanceof TimeSecVector) { + ((TimeSecVector) vector).setSafe(index, value); + return true; + } + return false; + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, false); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimestampAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimestampAvaticaParameterConverter.java new file mode 100644 index 0000000000000..3ded14d044073 --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimestampAvaticaParameterConverter.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.driver.jdbc.converter.impl; + +import org.apache.arrow.vector.FieldVector; +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.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +public class TimestampAvaticaParameterConverter extends BaseAvaticaParameterConverter { + + public TimestampAvaticaParameterConverter(ArrowType.Timestamp type) { + } + + @Override + public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + // FIXME: how should we handle TZ? Do we need to convert the value to the TZ on the vector? + long value = (long) typedValue.toLocal(); + if (vector instanceof TimeStampSecVector) { + ((TimeStampSecVector) vector).setSafe(index, value); + return true; + } else if (vector instanceof TimeStampMicroVector) { + ((TimeStampMicroVector) vector).setSafe(index, value); + return true; + } else if (vector instanceof TimeStampMilliVector) { + ((TimeStampMilliVector) vector).setSafe(index, value); + return true; + } else if (vector instanceof TimeStampNanoVector) { + ((TimeStampNanoVector) vector).setSafe(index, value); + return true; + } else if (vector instanceof TimeStampSecTZVector) { + ((TimeStampSecTZVector) vector).setSafe(index, value); + return true; + } else if (vector instanceof TimeStampMicroTZVector) { + ((TimeStampMicroTZVector) vector).setSafe(index, value); + return true; + } else if (vector instanceof TimeStampMilliTZVector) { + ((TimeStampMilliTZVector) vector).setSafe(index, value); + return true; + } else if (vector instanceof TimeStampNanoTZVector) { + ((TimeStampNanoTZVector) vector).setSafe(index, value); + return true; + } + return false; + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, false); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/Utf8AvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/Utf8AvaticaParameterConverter.java new file mode 100644 index 0000000000000..898a2de64276f --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/Utf8AvaticaParameterConverter.java @@ -0,0 +1,47 @@ +/* + * 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.driver.jdbc.converter.impl; + +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.VarCharVector; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.arrow.vector.util.Text; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +public class Utf8AvaticaParameterConverter extends BaseAvaticaParameterConverter { + + public Utf8AvaticaParameterConverter(ArrowType.Utf8 type) { + } + + @Override + public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + Object value = typedValue.toLocal(); + if (vector instanceof VarCharVector) { + ((VarCharVector) vector).setSafe(index, new Text((String) value)); + return true; + } + return false; + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, false); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java deleted file mode 100644 index c5c4cfdd69244..0000000000000 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowToJdbcUtils.java +++ /dev/null @@ -1,152 +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.driver.jdbc.utils; - -import java.math.BigDecimal; -import java.sql.Date; -import java.sql.Time; -import java.sql.Timestamp; -import java.sql.Types; -import java.util.ArrayList; -import java.util.HashMap; - -import org.apache.arrow.vector.types.FloatingPointPrecision; -import org.apache.arrow.vector.types.pojo.ArrowType; - -/** - * Helper class to convert Arrow types to JDBC required values. - */ -class ArrowToJdbcUtils { - static boolean isSigned(ArrowType type) { - switch (type.getTypeID()) { - case Int: - return ((ArrowType.Int) type).getIsSigned(); - case FloatingPoint: - case Decimal: - case Interval: - case Duration: - return true; - default: - return false; - } - } - - static int toJdbcType(ArrowType type) { - switch (type.getTypeID()) { - case Null: - return Types.NULL; - case Struct: - return Types.STRUCT; - case List: - case LargeList: - case FixedSizeList: - return Types.ARRAY; - case Int: - switch (((ArrowType.Int) type).getBitWidth()) { - case 64: - return Types.BIGINT; - case 32: - return Types.INTEGER; - case 16: - return Types.SMALLINT; - case 8: - return Types.TINYINT; - default: - // FIXME: Does this ever even happen? - return Types.OTHER; - } - case FloatingPoint: - /* - * These are a bit confusing. The following are equivalent: - * - * Highest precision: - * - JDBC REAL - * - Arrow DOUBLE - * - * Lower precision: - * - JDBC FLOAT - * - JDBC DOUBLE - * - Arrow SINGLE - * - Arrow HALF - */ - return ((ArrowType.FloatingPoint) type).getPrecision() == FloatingPointPrecision.DOUBLE ? - Types.REAL : Types.DOUBLE; - case Utf8: - case LargeUtf8: - return Types.VARCHAR; - case Binary: - case LargeBinary: - return Types.VARBINARY; - case FixedSizeBinary: - return Types.BINARY; - case Bool: - return Types.BOOLEAN; - case Decimal: - return Types.DECIMAL; - case Date: - return Types.DATE; - case Time: - return Types.TIME; - case Timestamp: - return Types.TIMESTAMP; - case Interval: - case Duration: - default: - return Types.OTHER; - } - - } - - static String getClassName(ArrowType type) { - switch (type.getTypeID()) { - case List: - case LargeList: - case FixedSizeList: - return ArrayList.class.getCanonicalName(); - case Map: - return HashMap.class.getCanonicalName(); - case Int: - return ((ArrowType.Int) type).getBitWidth() == 64 ? - long.class.getCanonicalName() : int.class.getCanonicalName(); - case FloatingPoint: - return ((ArrowType.FloatingPoint) type).getPrecision() == FloatingPointPrecision.DOUBLE ? - double.class.getCanonicalName() : float.class.getCanonicalName(); - case Utf8: - case LargeUtf8: - return String.class.getCanonicalName(); - case Binary: - case LargeBinary: - case FixedSizeBinary: - return byte[].class.getCanonicalName(); - case Bool: - return boolean.class.getCanonicalName(); - case Decimal: - return BigDecimal.class.getCanonicalName(); - case Date: - return Date.class.getCanonicalName(); - case Time: - return Time.class.getCanonicalName(); - case Timestamp: - case Interval: - case Duration: - return Timestamp.class.getCanonicalName(); - default: - return null; - } - } -} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java new file mode 100644 index 0000000000000..ac47298e8e84d --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java @@ -0,0 +1,65 @@ +/* + * 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.driver.jdbc.utils; + +import java.util.List; + +import org.apache.arrow.driver.jdbc.client.ArrowFlightSqlClientHandler.PreparedStatement; +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.vector.VectorSchemaRoot; +import org.apache.calcite.avatica.remote.TypedValue; + +/** + * Convert Avatica PreparedStatement parameters from a list of TypedValue to Arrow and bind them to the + * VectorSchemaRoot representing the PreparedStatement parameters. + *

+ * NOTE: Make sure to close the parameters VectorSchemaRoot once we're done with them. + */ +public class AvaticaParameterBinder { + private final PreparedStatement preparedStatement; + private final VectorSchemaRoot parameters; + + public AvaticaParameterBinder(PreparedStatement preparedStatement, BufferAllocator bufferAllocator) { + this.parameters = VectorSchemaRoot.create(preparedStatement.getParameterSchema(), bufferAllocator); + this.preparedStatement = preparedStatement; + } + + /** + * Bind the given Avatica values to the prepared statement. + * @param typedValues The parameter values. + */ + public void bind(List typedValues) { + if (preparedStatement.getParameterSchema().getFields().size() != typedValues.size()) { + throw new IllegalStateException( + String.format("Prepared statement has %s parameters, but only received %s", + preparedStatement.getParameterSchema().getFields().size(), + typedValues.size())); + } + + for (int i = 0; i < typedValues.size(); i++) { + TypedValueVectorBinder.bind(parameters.getVector(i), typedValues.get(i), 0); + } + + if (!typedValues.isEmpty()) { + parameters.setRowCount(1); + preparedStatement.setParameters(parameters); + } + } +} + + diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/TypedValueBinder.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/TypedValueBinder.java deleted file mode 100644 index 7d12bfa589616..0000000000000 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/TypedValueBinder.java +++ /dev/null @@ -1,126 +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.driver.jdbc.utils; - -import java.math.BigDecimal; -import java.util.List; - -import org.apache.arrow.driver.jdbc.client.ArrowFlightSqlClientHandler.PreparedStatement; -import org.apache.arrow.memory.BufferAllocator; -import org.apache.arrow.vector.BigIntVector; -import org.apache.arrow.vector.BitVector; -import org.apache.arrow.vector.DateMilliVector; -import org.apache.arrow.vector.DecimalVector; -import org.apache.arrow.vector.FieldVector; -import org.apache.arrow.vector.Float4Vector; -import org.apache.arrow.vector.Float8Vector; -import org.apache.arrow.vector.IntVector; -import org.apache.arrow.vector.LargeVarBinaryVector; -import org.apache.arrow.vector.LargeVarCharVector; -import org.apache.arrow.vector.NullVector; -import org.apache.arrow.vector.VarBinaryVector; -import org.apache.arrow.vector.VarCharVector; -import org.apache.arrow.vector.VectorSchemaRoot; -import org.apache.arrow.vector.util.Text; -import org.apache.calcite.avatica.remote.TypedValue; -import org.joda.time.DateTime; -import org.joda.time.format.DateTimeFormat; - -/** - * Bind {@link TypedValue}s to a {@link VectorSchemaRoot}. - * - * NOTE: Make sure to close the parameters VectorSchemaRoot once we're done with them. - */ -public class TypedValueBinder { - private final PreparedStatement preparedStatement; - private final VectorSchemaRoot parameters; - - public TypedValueBinder(PreparedStatement preparedStatement, BufferAllocator bufferAllocator) { - this.parameters = VectorSchemaRoot.create(preparedStatement.getParameterSchema(), bufferAllocator); - this.preparedStatement = preparedStatement; - } - - /** - * Bind the given Avatica values to the prepared statement. - * @param typedValues The parameter values. - */ - public void bind(List typedValues) { - if (preparedStatement.getParameterSchema().getFields().size() != typedValues.size()) { - throw new IllegalStateException( - String.format("Prepared statement has %s parameters, but only received %s", - preparedStatement.getParameterSchema().getFields().size(), - typedValues.size())); - } - - for (int i = 0; i < typedValues.size(); i++) { - final TypedValue param = typedValues.get(i); - final FieldVector vector = parameters.getVector(i); - bindValue(param, vector); - } - - if (!typedValues.isEmpty()) { - parameters.setRowCount(1); - preparedStatement.setParameters(parameters); - } - } - - private void bindValue(TypedValue param, FieldVector vector) { - Object value = param.value; - try { - if (vector instanceof IntVector) { - ((IntVector) vector).setSafe(0, (int) value); - } else if (vector instanceof BigIntVector) { - BigIntVector longVec = (BigIntVector) vector; - if (value instanceof Long) { - longVec.setSafe(0, (long) value); - } else { - longVec.setSafe(0, (int) value); - } - } else if (vector instanceof BitVector) { - ((BitVector) vector).setSafe(0, (int) value); - } else if (vector instanceof Float4Vector) { - ((Float4Vector) vector).setSafe(0, (float) value); - } else if (vector instanceof Float8Vector) { - ((Float8Vector) vector).setSafe(0, (double) value); - } else if (vector instanceof DecimalVector) { - ((DecimalVector) vector).setSafe(0, (BigDecimal) value); - } else if (vector instanceof VarCharVector) { - ((VarCharVector) vector).setSafe(0, new Text((String) value)); - } else if (vector instanceof LargeVarCharVector) { - ((LargeVarCharVector) vector).setSafe(0, new Text((String) value)); - } else if (vector instanceof DateMilliVector) { - String pattern = "yyyy-MM-dd HH:mm:ss.SSS"; - DateTime dateTime = DateTime.parse((String) value, DateTimeFormat.forPattern(pattern)); - - ((DateMilliVector) vector).setSafe(0, dateTime.getMillis()); - } else if (vector instanceof VarBinaryVector) { - ((VarBinaryVector) vector).setSafe(0, (byte[]) value); - } else if (vector instanceof LargeVarBinaryVector) { - ((LargeVarBinaryVector) vector).setSafe(0, (byte[]) value); - } else if (vector instanceof NullVector) { - assert true; - } else { - throw new UnsupportedOperationException( - String.format("Binding to parameter of Arrow type %s", vector.getField().getType())); - } - } catch (ClassCastException e) { - throw new RuntimeException(String.format("Value of type %s is not compatible with Arrow type %s", - param.type, vector.getField().getType())); - } - } -} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/TypedValueVectorBinder.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/TypedValueVectorBinder.java new file mode 100644 index 0000000000000..567c98e7e3e77 --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/TypedValueVectorBinder.java @@ -0,0 +1,180 @@ +/* + * 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.driver.jdbc.utils; + +import org.apache.arrow.driver.jdbc.converter.impl.BinaryAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.BoolAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.DateAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.DecimalAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.DurationAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.FixedSizeBinaryAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.FloatingPointAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.IntAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.IntervalAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.LargeBinaryAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.LargeUtf8AvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.NullAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.TimeAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.TimestampAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.Utf8AvaticaParameterConverter; +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.calcite.avatica.remote.TypedValue; + +/** + * Bind an Avatica TypedValue to a FieldVector using an ArrowTypeVisitor. + */ +public class TypedValueVectorBinder { + /** + * Bind a TypedValue to the given index on the FieldVctor. + * + * @param vector FieldVector to bind to. + * @param typedValue TypedValue to bind to the vector. + * @param index Vector index to bind the value at. + */ + static void bind(FieldVector vector, TypedValue typedValue, int index) { + try { + if (!vector.getField().getType().accept(new BinderVisitor(vector, typedValue, index))) { + throw new UnsupportedOperationException( + String.format("Binding to vector type %s is not yet supported", vector.getClass())); + } + } catch (ClassCastException e) { + throw new RuntimeException(String.format("Value of type %s is not compatible with Arrow type %s", + typedValue.type, vector.getField().getType())); + } + } + + private static class BinderVisitor implements ArrowType.ArrowTypeVisitor { + private final FieldVector vector; + private final TypedValue typedValue; + private final Object value; + private final int index; + + private BinderVisitor(FieldVector vector, TypedValue value, int index) { + this.vector = vector; + this.typedValue = value; + this.value = value.value; + this.index = index; + } + + @Override + public Boolean visit(ArrowType.Null type) { + return new NullAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.Struct type) { + return false; + } + + @Override + public Boolean visit(ArrowType.List type) { + return false; + } + + @Override + public Boolean visit(ArrowType.LargeList type) { + return false; + } + + @Override + public Boolean visit(ArrowType.FixedSizeList type) { + return false; + } + + @Override + public Boolean visit(ArrowType.Union type) { + return false; + } + + @Override + public Boolean visit(ArrowType.Map type) { + return false; + } + + @Override + public Boolean visit(ArrowType.Int type) { + return new IntAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.FloatingPoint type) { + return new FloatingPointAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.Utf8 type) { + return new Utf8AvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.LargeUtf8 type) { + return new LargeUtf8AvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.Binary type) { + return new BinaryAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.LargeBinary type) { + return new LargeBinaryAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.FixedSizeBinary type) { + return new FixedSizeBinaryAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.Bool type) { + return new BoolAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.Decimal type) { + return new DecimalAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.Date type) { + return new DateAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.Time type) { + return new TimeAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.Timestamp type) { + return new TimestampAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.Interval type) { + return new IntervalAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.Duration type) { + return new DurationAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/utils/ConvertUtilsTest.java b/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/utils/ConvertUtilsTest.java index 5cea3749283d7..3b6636d498c19 100644 --- a/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/utils/ConvertUtilsTest.java +++ b/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/utils/ConvertUtilsTest.java @@ -21,6 +21,7 @@ import java.util.List; +import org.apache.arrow.driver.jdbc.converter.ConvertUtils; import org.apache.arrow.flight.sql.FlightSqlColumnMetadata; import org.apache.arrow.vector.types.pojo.ArrowType; import org.apache.arrow.vector.types.pojo.Field; From eb087cba032a2786391618fdfda58817c7c0533c Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Mon, 30 Oct 2023 17:26:42 +0000 Subject: [PATCH 11/21] Simplify --- .../driver/jdbc/ArrowFlightMetaImpl.java | 18 +- .../jdbc/utils/AvaticaParameterBinder.java | 167 +++++++++++++++- .../jdbc/utils/TypedValueVectorBinder.java | 180 ------------------ .../arrow/flight/sql/FlightSqlClient.java | 2 +- 4 files changed, 183 insertions(+), 184 deletions(-) delete mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/TypedValueVectorBinder.java diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java index 91b942daf2534..c68515fba9e99 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java @@ -128,7 +128,23 @@ public ExecuteResult execute(final StatementHandle statementHandle, public ExecuteBatchResult executeBatch(final StatementHandle statementHandle, final List> parameterValuesList) throws IllegalStateException { - throw new IllegalStateException("executeBatch not implemented."); + Preconditions.checkArgument(connection.id.equals(statementHandle.connectionId), + "Connection IDs are not consistent"); + PreparedStatement preparedStatement = getPreparedStatement(statementHandle); + + if (preparedStatement == null) { + throw new IllegalStateException("Prepared statement not found: " + statementHandle); + } + + final AvaticaParameterBinder binder = + new AvaticaParameterBinder(preparedStatement, ((ArrowFlightConnection) connection).getBufferAllocator()); + for (int i = 0; i < parameterValuesList.size(); i++) { + binder.bind(parameterValuesList.get(i), i); + } + + // Update query + long[] updatedCounts = {preparedStatement.executeUpdate()}; + return new ExecuteBatchResult(updatedCounts); } @Override diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java index ac47298e8e84d..b87708648c37b 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java @@ -20,8 +20,25 @@ import java.util.List; import org.apache.arrow.driver.jdbc.client.ArrowFlightSqlClientHandler.PreparedStatement; +import org.apache.arrow.driver.jdbc.converter.impl.BinaryAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.BoolAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.DateAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.DecimalAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.DurationAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.FixedSizeBinaryAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.FloatingPointAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.IntAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.IntervalAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.LargeBinaryAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.LargeUtf8AvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.NullAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.TimeAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.TimestampAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.Utf8AvaticaParameterConverter; import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.vector.FieldVector; import org.apache.arrow.vector.VectorSchemaRoot; +import org.apache.arrow.vector.types.pojo.ArrowType; import org.apache.calcite.avatica.remote.TypedValue; /** @@ -44,6 +61,15 @@ public AvaticaParameterBinder(PreparedStatement preparedStatement, BufferAllocat * @param typedValues The parameter values. */ public void bind(List typedValues) { + bind(typedValues, 0); + } + + /** + * Bind the given Avatica values to the prepared statement at the given index. + * @param typedValues The parameter values. + * @param index index for parameter. + */ + public void bind(List typedValues, int index) { if (preparedStatement.getParameterSchema().getFields().size() != typedValues.size()) { throw new IllegalStateException( String.format("Prepared statement has %s parameters, but only received %s", @@ -52,14 +78,151 @@ public void bind(List typedValues) { } for (int i = 0; i < typedValues.size(); i++) { - TypedValueVectorBinder.bind(parameters.getVector(i), typedValues.get(i), 0); + bind(parameters.getVector(i), typedValues.get(i), index); } if (!typedValues.isEmpty()) { - parameters.setRowCount(1); + parameters.setRowCount(index + 1); preparedStatement.setParameters(parameters); } } + + /** + * Bind a TypedValue to the given index on the FieldVctor. + * + * @param vector FieldVector to bind to. + * @param typedValue TypedValue to bind to the vector. + * @param index Vector index to bind the value at. + */ + private void bind(FieldVector vector, TypedValue typedValue, int index) { + try { + if (!vector.getField().getType().accept(new BinderVisitor(vector, typedValue, index))) { + throw new UnsupportedOperationException( + String.format("Binding to vector type %s is not yet supported", vector.getClass())); + } + } catch (ClassCastException e) { + throw new RuntimeException(String.format("Value of type %s is not compatible with Arrow type %s", + typedValue.type, vector.getField().getType())); + } + } + + private static class BinderVisitor implements ArrowType.ArrowTypeVisitor { + private final FieldVector vector; + private final TypedValue typedValue; + private final int index; + + private BinderVisitor(FieldVector vector, TypedValue value, int index) { + this.vector = vector; + this.typedValue = value; + this.index = index; + } + + @Override + public Boolean visit(ArrowType.Null type) { + return new NullAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.Struct type) { + return false; + } + + @Override + public Boolean visit(ArrowType.List type) { + return false; + } + + @Override + public Boolean visit(ArrowType.LargeList type) { + return false; + } + + @Override + public Boolean visit(ArrowType.FixedSizeList type) { + return false; + } + + @Override + public Boolean visit(ArrowType.Union type) { + return false; + } + + @Override + public Boolean visit(ArrowType.Map type) { + return false; + } + + @Override + public Boolean visit(ArrowType.Int type) { + return new IntAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.FloatingPoint type) { + return new FloatingPointAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.Utf8 type) { + return new Utf8AvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.LargeUtf8 type) { + return new LargeUtf8AvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.Binary type) { + return new BinaryAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.LargeBinary type) { + return new LargeBinaryAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.FixedSizeBinary type) { + return new FixedSizeBinaryAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.Bool type) { + return new BoolAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.Decimal type) { + return new DecimalAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.Date type) { + return new DateAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.Time type) { + return new TimeAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.Timestamp type) { + return new TimestampAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.Interval type) { + return new IntervalAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + + @Override + public Boolean visit(ArrowType.Duration type) { + return new DurationAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + } + } + } diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/TypedValueVectorBinder.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/TypedValueVectorBinder.java deleted file mode 100644 index 567c98e7e3e77..0000000000000 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/TypedValueVectorBinder.java +++ /dev/null @@ -1,180 +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.driver.jdbc.utils; - -import org.apache.arrow.driver.jdbc.converter.impl.BinaryAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.BoolAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.DateAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.DecimalAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.DurationAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.FixedSizeBinaryAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.FloatingPointAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.IntAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.IntervalAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.LargeBinaryAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.LargeUtf8AvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.NullAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.TimeAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.TimestampAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.Utf8AvaticaParameterConverter; -import org.apache.arrow.vector.FieldVector; -import org.apache.arrow.vector.types.pojo.ArrowType; -import org.apache.calcite.avatica.remote.TypedValue; - -/** - * Bind an Avatica TypedValue to a FieldVector using an ArrowTypeVisitor. - */ -public class TypedValueVectorBinder { - /** - * Bind a TypedValue to the given index on the FieldVctor. - * - * @param vector FieldVector to bind to. - * @param typedValue TypedValue to bind to the vector. - * @param index Vector index to bind the value at. - */ - static void bind(FieldVector vector, TypedValue typedValue, int index) { - try { - if (!vector.getField().getType().accept(new BinderVisitor(vector, typedValue, index))) { - throw new UnsupportedOperationException( - String.format("Binding to vector type %s is not yet supported", vector.getClass())); - } - } catch (ClassCastException e) { - throw new RuntimeException(String.format("Value of type %s is not compatible with Arrow type %s", - typedValue.type, vector.getField().getType())); - } - } - - private static class BinderVisitor implements ArrowType.ArrowTypeVisitor { - private final FieldVector vector; - private final TypedValue typedValue; - private final Object value; - private final int index; - - private BinderVisitor(FieldVector vector, TypedValue value, int index) { - this.vector = vector; - this.typedValue = value; - this.value = value.value; - this.index = index; - } - - @Override - public Boolean visit(ArrowType.Null type) { - return new NullAvaticaParameterConverter(type).setParameter(vector, typedValue, index); - } - - @Override - public Boolean visit(ArrowType.Struct type) { - return false; - } - - @Override - public Boolean visit(ArrowType.List type) { - return false; - } - - @Override - public Boolean visit(ArrowType.LargeList type) { - return false; - } - - @Override - public Boolean visit(ArrowType.FixedSizeList type) { - return false; - } - - @Override - public Boolean visit(ArrowType.Union type) { - return false; - } - - @Override - public Boolean visit(ArrowType.Map type) { - return false; - } - - @Override - public Boolean visit(ArrowType.Int type) { - return new IntAvaticaParameterConverter(type).setParameter(vector, typedValue, index); - } - - @Override - public Boolean visit(ArrowType.FloatingPoint type) { - return new FloatingPointAvaticaParameterConverter(type).setParameter(vector, typedValue, index); - } - - @Override - public Boolean visit(ArrowType.Utf8 type) { - return new Utf8AvaticaParameterConverter(type).setParameter(vector, typedValue, index); - } - - @Override - public Boolean visit(ArrowType.LargeUtf8 type) { - return new LargeUtf8AvaticaParameterConverter(type).setParameter(vector, typedValue, index); - } - - @Override - public Boolean visit(ArrowType.Binary type) { - return new BinaryAvaticaParameterConverter(type).setParameter(vector, typedValue, index); - } - - @Override - public Boolean visit(ArrowType.LargeBinary type) { - return new LargeBinaryAvaticaParameterConverter(type).setParameter(vector, typedValue, index); - } - - @Override - public Boolean visit(ArrowType.FixedSizeBinary type) { - return new FixedSizeBinaryAvaticaParameterConverter(type).setParameter(vector, typedValue, index); - } - - @Override - public Boolean visit(ArrowType.Bool type) { - return new BoolAvaticaParameterConverter(type).setParameter(vector, typedValue, index); - } - - @Override - public Boolean visit(ArrowType.Decimal type) { - return new DecimalAvaticaParameterConverter(type).setParameter(vector, typedValue, index); - } - - @Override - public Boolean visit(ArrowType.Date type) { - return new DateAvaticaParameterConverter(type).setParameter(vector, typedValue, index); - } - - @Override - public Boolean visit(ArrowType.Time type) { - return new TimeAvaticaParameterConverter(type).setParameter(vector, typedValue, index); - } - - @Override - public Boolean visit(ArrowType.Timestamp type) { - return new TimestampAvaticaParameterConverter(type).setParameter(vector, typedValue, index); - } - - @Override - public Boolean visit(ArrowType.Interval type) { - return new IntervalAvaticaParameterConverter(type).setParameter(vector, typedValue, index); - } - - @Override - public Boolean visit(ArrowType.Duration type) { - return new DurationAvaticaParameterConverter(type).setParameter(vector, typedValue, index); - } - } -} diff --git a/java/flight/flight-sql/src/main/java/org/apache/arrow/flight/sql/FlightSqlClient.java b/java/flight/flight-sql/src/main/java/org/apache/arrow/flight/sql/FlightSqlClient.java index 82fc785940760..93d933f00f38f 100644 --- a/java/flight/flight-sql/src/main/java/org/apache/arrow/flight/sql/FlightSqlClient.java +++ b/java/flight/flight-sql/src/main/java/org/apache/arrow/flight/sql/FlightSqlClient.java @@ -951,7 +951,7 @@ public static class PreparedStatement implements AutoCloseable { * {@code PreparedStatement} setters. */ public void setParameters(final VectorSchemaRoot parameterBindingRoot) { - if (parameterBindingRoot.equals(this.parameterBindingRoot)) { + if (parameterBindingRoot == this.parameterBindingRoot) { // Nothing to do if we're attempting to set the same parameters again. return; } From cc3ea42ba8fea43842bb3de5de7d89782dd30ab5 Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Mon, 30 Oct 2023 17:34:32 +0000 Subject: [PATCH 12/21] Simplify more --- .../ArrowFieldToAvaticaParameter.java | 162 ------------------ .../driver/jdbc/converter/ConvertUtils.java | 131 +++++++++++++- 2 files changed, 130 insertions(+), 163 deletions(-) delete mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/ArrowFieldToAvaticaParameter.java diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/ArrowFieldToAvaticaParameter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/ArrowFieldToAvaticaParameter.java deleted file mode 100644 index 86a1778805049..0000000000000 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/ArrowFieldToAvaticaParameter.java +++ /dev/null @@ -1,162 +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.driver.jdbc.converter; - -import org.apache.arrow.driver.jdbc.converter.impl.BinaryAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.BoolAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.DateAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.DecimalAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.DurationAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.FixedSizeBinaryAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.FloatingPointAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.IntAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.IntervalAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.LargeBinaryAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.LargeUtf8AvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.NullAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.TimeAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.TimestampAvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.converter.impl.Utf8AvaticaParameterConverter; -import org.apache.arrow.vector.types.pojo.ArrowType; -import org.apache.arrow.vector.types.pojo.Field; -import org.apache.calcite.avatica.AvaticaParameter; - -/** - * Create a - */ -public class ArrowFieldToAvaticaParameter { - /** - * Bind a TypedValue to the given index on the FieldVctor. - */ - static AvaticaParameter convert(Field field) { - return field.getType().accept(new ConverterVisitor(field)); - } - - private static class ConverterVisitor implements ArrowType.ArrowTypeVisitor { - private final Field field; - - private ConverterVisitor(Field field) { - this.field = field; - } - - @Override - public AvaticaParameter visit(ArrowType.Null type) { - return new NullAvaticaParameterConverter(type).createParameter(field); - } - - @Override - public AvaticaParameter visit(ArrowType.Struct type) { - throw new UnsupportedOperationException(); - } - - @Override - public AvaticaParameter visit(ArrowType.List type) { - throw new UnsupportedOperationException(); - } - - @Override - public AvaticaParameter visit(ArrowType.LargeList type) { - throw new UnsupportedOperationException(); - } - - @Override - public AvaticaParameter visit(ArrowType.FixedSizeList type) { - throw new UnsupportedOperationException(); - } - - @Override - public AvaticaParameter visit(ArrowType.Union type) { - throw new UnsupportedOperationException(); - } - - @Override - public AvaticaParameter visit(ArrowType.Map type) { - throw new UnsupportedOperationException(); - } - - @Override - public AvaticaParameter visit(ArrowType.Int type) { - return new IntAvaticaParameterConverter(type).createParameter(field); - } - - @Override - public AvaticaParameter visit(ArrowType.FloatingPoint type) { - return new FloatingPointAvaticaParameterConverter(type).createParameter(field); - } - - @Override - public AvaticaParameter visit(ArrowType.Utf8 type) { - return new Utf8AvaticaParameterConverter(type).createParameter(field); - } - - @Override - public AvaticaParameter visit(ArrowType.LargeUtf8 type) { - return new LargeUtf8AvaticaParameterConverter(type).createParameter(field); - } - - @Override - public AvaticaParameter visit(ArrowType.Binary type) { - return new BinaryAvaticaParameterConverter(type).createParameter(field); - } - - @Override - public AvaticaParameter visit(ArrowType.LargeBinary type) { - return new LargeBinaryAvaticaParameterConverter(type).createParameter(field); - } - - @Override - public AvaticaParameter visit(ArrowType.FixedSizeBinary type) { - return new FixedSizeBinaryAvaticaParameterConverter(type).createParameter(field); - } - - @Override - public AvaticaParameter visit(ArrowType.Bool type) { - return new BoolAvaticaParameterConverter(type).createParameter(field); - } - - @Override - public AvaticaParameter visit(ArrowType.Decimal type) { - return new DecimalAvaticaParameterConverter(type).createParameter(field); - } - - @Override - public AvaticaParameter visit(ArrowType.Date type) { - return new DateAvaticaParameterConverter(type).createParameter(field); - } - - @Override - public AvaticaParameter visit(ArrowType.Time type) { - return new TimeAvaticaParameterConverter(type).createParameter(field); - } - - @Override - public AvaticaParameter visit(ArrowType.Timestamp type) { - return new TimestampAvaticaParameterConverter(type).createParameter(field); - } - - @Override - public AvaticaParameter visit(ArrowType.Interval type) { - return new IntervalAvaticaParameterConverter(type).createParameter(field); - } - - @Override - public AvaticaParameter visit(ArrowType.Duration type) { - return new DurationAvaticaParameterConverter(type).createParameter(field); - } - } -} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/ConvertUtils.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/ConvertUtils.java index dca4e3ec254ad..cd5961bf242e1 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/ConvertUtils.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/ConvertUtils.java @@ -22,6 +22,21 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.apache.arrow.driver.jdbc.converter.impl.BinaryAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.BoolAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.DateAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.DecimalAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.DurationAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.FixedSizeBinaryAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.FloatingPointAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.IntAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.IntervalAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.LargeBinaryAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.LargeUtf8AvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.NullAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.TimeAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.TimestampAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.Utf8AvaticaParameterConverter; import org.apache.arrow.driver.jdbc.utils.SqlTypes; import org.apache.arrow.flight.sql.FlightSqlColumnMetadata; import org.apache.arrow.vector.types.pojo.ArrowType; @@ -123,6 +138,120 @@ public static void setOnColumnMetaDataBuilder(final Builder builder, * @return list of {@link AvaticaParameter}. */ public static List convertArrowFieldsToAvaticaParameters(final List fields) { - return fields.stream().map(ArrowFieldToAvaticaParameter::convert).collect(Collectors.toList()); + return fields.stream().map( field -> field.getType().accept(new ConverterVisitor(field))).collect(Collectors.toList()); } + + private static class ConverterVisitor implements ArrowType.ArrowTypeVisitor { + private final Field field; + + private ConverterVisitor(Field field) { + this.field = field; + } + + @Override + public AvaticaParameter visit(ArrowType.Null type) { + return new NullAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.Struct type) { + throw new UnsupportedOperationException(); + } + + @Override + public AvaticaParameter visit(ArrowType.List type) { + throw new UnsupportedOperationException(); + } + + @Override + public AvaticaParameter visit(ArrowType.LargeList type) { + throw new UnsupportedOperationException(); + } + + @Override + public AvaticaParameter visit(ArrowType.FixedSizeList type) { + throw new UnsupportedOperationException(); + } + + @Override + public AvaticaParameter visit(ArrowType.Union type) { + throw new UnsupportedOperationException(); + } + + @Override + public AvaticaParameter visit(ArrowType.Map type) { + throw new UnsupportedOperationException(); + } + + @Override + public AvaticaParameter visit(ArrowType.Int type) { + return new IntAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.FloatingPoint type) { + return new FloatingPointAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.Utf8 type) { + return new Utf8AvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.LargeUtf8 type) { + return new LargeUtf8AvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.Binary type) { + return new BinaryAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.LargeBinary type) { + return new LargeBinaryAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.FixedSizeBinary type) { + return new FixedSizeBinaryAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.Bool type) { + return new BoolAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.Decimal type) { + return new DecimalAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.Date type) { + return new DateAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.Time type) { + return new TimeAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.Timestamp type) { + return new TimestampAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.Interval type) { + return new IntervalAvaticaParameterConverter(type).createParameter(field); + } + + @Override + public AvaticaParameter visit(ArrowType.Duration type) { + return new DurationAvaticaParameterConverter(type).createParameter(field); + } + } + } From cf658a3f29a7e230b1e991343463cfca910d49dc Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Mon, 30 Oct 2023 17:36:41 +0000 Subject: [PATCH 13/21] Move back convertutils --- .../driver/jdbc/ArrowFlightJdbcVectorSchemaRootResultSet.java | 2 +- .../java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java | 2 +- .../org/apache/arrow/driver/jdbc/ArrowFlightStatement.java | 2 +- .../arrow/driver/jdbc/{converter => utils}/ConvertUtils.java | 3 +-- .../org/apache/arrow/driver/jdbc/utils/ConvertUtilsTest.java | 1 - 5 files changed, 4 insertions(+), 6 deletions(-) rename java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/{converter => utils}/ConvertUtils.java (98%) diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcVectorSchemaRootResultSet.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcVectorSchemaRootResultSet.java index 99402636e799b..788ae6e8de3ef 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcVectorSchemaRootResultSet.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcVectorSchemaRootResultSet.java @@ -26,7 +26,7 @@ import java.util.Set; import java.util.TimeZone; -import org.apache.arrow.driver.jdbc.converter.ConvertUtils; +import org.apache.arrow.driver.jdbc.utils.ConvertUtils; import org.apache.arrow.util.AutoCloseables; import org.apache.arrow.vector.VectorSchemaRoot; import org.apache.arrow.vector.types.pojo.Schema; diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java index c68515fba9e99..03b7f3c6425ac 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java @@ -27,7 +27,7 @@ import java.util.concurrent.ConcurrentHashMap; import org.apache.arrow.driver.jdbc.client.ArrowFlightSqlClientHandler.PreparedStatement; -import org.apache.arrow.driver.jdbc.converter.ConvertUtils; +import org.apache.arrow.driver.jdbc.utils.ConvertUtils; import org.apache.arrow.driver.jdbc.utils.AvaticaParameterBinder; import org.apache.arrow.util.Preconditions; import org.apache.arrow.vector.types.pojo.Schema; diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightStatement.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightStatement.java index a73c5f9d4bb9d..5bc7c2ab9b4f8 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightStatement.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightStatement.java @@ -20,7 +20,7 @@ import java.sql.SQLException; import org.apache.arrow.driver.jdbc.client.ArrowFlightSqlClientHandler.PreparedStatement; -import org.apache.arrow.driver.jdbc.converter.ConvertUtils; +import org.apache.arrow.driver.jdbc.utils.ConvertUtils; import org.apache.arrow.flight.FlightInfo; import org.apache.arrow.vector.types.pojo.Schema; import org.apache.calcite.avatica.AvaticaStatement; diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/ConvertUtils.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java similarity index 98% rename from java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/ConvertUtils.java rename to java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java index cd5961bf242e1..68784ad1eedf8 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/ConvertUtils.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.arrow.driver.jdbc.converter; +package org.apache.arrow.driver.jdbc.utils; import java.util.List; import java.util.Map; @@ -37,7 +37,6 @@ import org.apache.arrow.driver.jdbc.converter.impl.TimeAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.TimestampAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.Utf8AvaticaParameterConverter; -import org.apache.arrow.driver.jdbc.utils.SqlTypes; import org.apache.arrow.flight.sql.FlightSqlColumnMetadata; import org.apache.arrow.vector.types.pojo.ArrowType; import org.apache.arrow.vector.types.pojo.Field; diff --git a/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/utils/ConvertUtilsTest.java b/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/utils/ConvertUtilsTest.java index 3b6636d498c19..5cea3749283d7 100644 --- a/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/utils/ConvertUtilsTest.java +++ b/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/utils/ConvertUtilsTest.java @@ -21,7 +21,6 @@ import java.util.List; -import org.apache.arrow.driver.jdbc.converter.ConvertUtils; import org.apache.arrow.flight.sql.FlightSqlColumnMetadata; import org.apache.arrow.vector.types.pojo.ArrowType; import org.apache.arrow.vector.types.pojo.Field; From 84b1c9198197db235999132e526098ed271e6169 Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Mon, 30 Oct 2023 18:05:16 +0000 Subject: [PATCH 14/21] formatting and rename setParameter -> bindParameter --- .../driver/jdbc/ArrowFlightMetaImpl.java | 12 ++++---- .../converter/AvaticaParameterConverter.java | 16 +++++++++- .../impl/BinaryAvaticaParameterConverter.java | 2 +- .../impl/BoolAvaticaParameterConverter.java | 2 +- .../impl/DateAvaticaParameterConverter.java | 2 +- .../DecimalAvaticaParameterConverter.java | 2 +- .../DurationAvaticaParameterConverter.java | 2 +- ...edSizeBinaryAvaticaParameterConverter.java | 2 +- ...loatingPointAvaticaParameterConverter.java | 18 +++++------ .../impl/IntAvaticaParameterConverter.java | 2 +- .../IntervalAvaticaParameterConverter.java | 2 +- .../LargeBinaryAvaticaParameterConverter.java | 2 +- .../LargeUtf8AvaticaParameterConverter.java | 2 +- .../impl/NullAvaticaParameterConverter.java | 2 +- .../impl/TimeAvaticaParameterConverter.java | 2 +- .../TimestampAvaticaParameterConverter.java | 2 +- .../impl/Utf8AvaticaParameterConverter.java | 2 +- .../jdbc/utils/AvaticaParameterBinder.java | 30 +++++++++---------- 18 files changed, 59 insertions(+), 45 deletions(-) diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java index 03b7f3c6425ac..382750914992f 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightMetaImpl.java @@ -27,8 +27,8 @@ import java.util.concurrent.ConcurrentHashMap; import org.apache.arrow.driver.jdbc.client.ArrowFlightSqlClientHandler.PreparedStatement; -import org.apache.arrow.driver.jdbc.utils.ConvertUtils; import org.apache.arrow.driver.jdbc.utils.AvaticaParameterBinder; +import org.apache.arrow.driver.jdbc.utils.ConvertUtils; import org.apache.arrow.util.Preconditions; import org.apache.arrow.vector.types.pojo.Schema; import org.apache.calcite.avatica.AvaticaConnection; @@ -100,9 +100,9 @@ public ExecuteResult execute(final StatementHandle statementHandle, throw new IllegalStateException("Prepared statement not found: " + statementHandle); } - final AvaticaParameterBinder binder = - new AvaticaParameterBinder(preparedStatement, ((ArrowFlightConnection) connection).getBufferAllocator()); - binder.bind(typedValues); + + new AvaticaParameterBinder(preparedStatement, ((ArrowFlightConnection) connection).getBufferAllocator()) + .bind(typedValues); if (statementHandle.signature == null) { // Update query @@ -136,8 +136,8 @@ public ExecuteBatchResult executeBatch(final StatementHandle statementHandle, throw new IllegalStateException("Prepared statement not found: " + statementHandle); } - final AvaticaParameterBinder binder = - new AvaticaParameterBinder(preparedStatement, ((ArrowFlightConnection) connection).getBufferAllocator()); + final AvaticaParameterBinder binder = new AvaticaParameterBinder(preparedStatement, + ((ArrowFlightConnection) connection).getBufferAllocator()); for (int i = 0; i < parameterValuesList.size(); i++) { binder.bind(parameterValuesList.get(i), i); } diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/AvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/AvaticaParameterConverter.java index 366575ad87434..c01e688f37396 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/AvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/AvaticaParameterConverter.java @@ -22,7 +22,21 @@ import org.apache.calcite.avatica.AvaticaParameter; import org.apache.calcite.avatica.remote.TypedValue; +/** + * Interface for a class in charge of converting between AvaticaParameters and TypedValues and + * Arrow. + */ public interface AvaticaParameterConverter { - boolean setParameter(FieldVector vector, TypedValue typedValue, int index); + + /** + * Bind a TypedValue to a FieldVector at the given index. + * + * @param vector FieldVector that the parameter should be bound to. + * @param typedValue TypedValue to bind as a parameter. + * @param index Vector index that the TypedValue should be bound to. + * @return Whether the value was set successfully. + */ + boolean bindParameter(FieldVector vector, TypedValue typedValue, int index); + AvaticaParameter createParameter(Field field); } diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BinaryAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BinaryAvaticaParameterConverter.java index ef2f1cfa3c662..b8a912073a8d1 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BinaryAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BinaryAvaticaParameterConverter.java @@ -30,7 +30,7 @@ public BinaryAvaticaParameterConverter(ArrowType.Binary type) { } @Override - public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { Object value = typedValue.toLocal(); if (vector instanceof VarBinaryVector) { ((VarBinaryVector) vector).setSafe(index, (byte[]) value); diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BoolAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BoolAvaticaParameterConverter.java index 74b01ddef4120..c84506878bc84 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BoolAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BoolAvaticaParameterConverter.java @@ -30,7 +30,7 @@ public BoolAvaticaParameterConverter(ArrowType.Bool type) { } @Override - public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { Object value = typedValue.toLocal(); if (vector instanceof BitVector) { ((BitVector) vector).setSafe(index, (int) value); diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DateAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DateAvaticaParameterConverter.java index dc0c5a6276173..8807fc65d4439 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DateAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DateAvaticaParameterConverter.java @@ -31,7 +31,7 @@ public DateAvaticaParameterConverter(ArrowType.Date type) { } @Override - public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { Object value = typedValue.toLocal(); if (vector instanceof DateMilliVector) { ((DateMilliVector) vector).setSafe(index, (int) value); diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DecimalAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DecimalAvaticaParameterConverter.java index 114d18c15dde5..ae8b379cd9f38 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DecimalAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DecimalAvaticaParameterConverter.java @@ -32,7 +32,7 @@ public DecimalAvaticaParameterConverter(ArrowType.Decimal type) { } @Override - public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { Object value = typedValue.toLocal(); if (vector instanceof DecimalVector) { ((DecimalVector) vector).setSafe(index, (BigDecimal) value); diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DurationAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DurationAvaticaParameterConverter.java index 4f89b86f51901..aa0dda37622ab 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DurationAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DurationAvaticaParameterConverter.java @@ -29,7 +29,7 @@ public DurationAvaticaParameterConverter(ArrowType.Duration type) { } @Override - public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { return false; } diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FixedSizeBinaryAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FixedSizeBinaryAvaticaParameterConverter.java index 46b776b3fb8b3..6d79c3ed96459 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FixedSizeBinaryAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FixedSizeBinaryAvaticaParameterConverter.java @@ -30,7 +30,7 @@ public FixedSizeBinaryAvaticaParameterConverter(ArrowType.FixedSizeBinary type) } @Override - public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { Object value = typedValue.toLocal(); if (vector instanceof FixedSizeBinaryVector) { ((FixedSizeBinaryVector) vector).setSafe(index, (byte[]) value); diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FloatingPointAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FloatingPointAvaticaParameterConverter.java index 7352aa810f9f3..dd84c611a89b3 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FloatingPointAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FloatingPointAvaticaParameterConverter.java @@ -31,16 +31,16 @@ public FloatingPointAvaticaParameterConverter(ArrowType.FloatingPoint type) { } @Override - public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { Object value = typedValue.toLocal(); - if (vector instanceof Float4Vector) { - ((Float4Vector) vector).setSafe(index, (float) value); - return true; - } else if (vector instanceof Float8Vector) { - ((Float8Vector) vector).setSafe(index, (double) value); - return true; - } - return false; + if (vector instanceof Float4Vector) { + ((Float4Vector) vector).setSafe(index, (float) value); + return true; + } else if (vector instanceof Float8Vector) { + ((Float8Vector) vector).setSafe(index, (double) value); + return true; + } + return false; } @Override diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntAvaticaParameterConverter.java index 21b79ee0c5221..911f53a49b42c 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntAvaticaParameterConverter.java @@ -39,7 +39,7 @@ public IntAvaticaParameterConverter(ArrowType.Int type) { } @Override - public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { Object value = typedValue.toLocal(); if (vector instanceof TinyIntVector) { ((TinyIntVector) vector).setSafe(index, (int) value); diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntervalAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntervalAvaticaParameterConverter.java index 68ada9aad9413..416dc33a2e494 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntervalAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntervalAvaticaParameterConverter.java @@ -29,7 +29,7 @@ public IntervalAvaticaParameterConverter(ArrowType.Interval type) { } @Override - public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { // Object value = typedValue.toLocal(); // if (vector instanceof IntervalDayVector) { // ((IntervalDayVector) vector).setSafe(index, () value); diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeBinaryAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeBinaryAvaticaParameterConverter.java index c55da41ab4403..4ef80293f40e2 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeBinaryAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeBinaryAvaticaParameterConverter.java @@ -30,7 +30,7 @@ public LargeBinaryAvaticaParameterConverter(ArrowType.LargeBinary type) { } @Override - public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { Object value = typedValue.toLocal(); if (vector instanceof LargeVarBinaryVector) { ((LargeVarBinaryVector) vector).setSafe(index, (byte[]) value); diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeUtf8AvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeUtf8AvaticaParameterConverter.java index 783bff2f8ad55..01df472eac093 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeUtf8AvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeUtf8AvaticaParameterConverter.java @@ -31,7 +31,7 @@ public LargeUtf8AvaticaParameterConverter(ArrowType.LargeUtf8 type) { } @Override - public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { Object value = typedValue.toLocal(); if (vector instanceof LargeVarCharVector) { ((LargeVarCharVector) vector).setSafe(index, new Text((String) value)); diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/NullAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/NullAvaticaParameterConverter.java index 9d3ce0c6d1fae..d64dd4195af9e 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/NullAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/NullAvaticaParameterConverter.java @@ -30,7 +30,7 @@ public NullAvaticaParameterConverter(ArrowType.Null type) { } @Override - public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { Object value = typedValue.toLocal(); if (vector instanceof NullVector) { if (value != null) throw new RuntimeException("Can't set non-null value on NullVector"); diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimeAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimeAvaticaParameterConverter.java index befe0b932c92d..d835b8df7ea9c 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimeAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimeAvaticaParameterConverter.java @@ -33,7 +33,7 @@ public TimeAvaticaParameterConverter(ArrowType.Time type) { } @Override - public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { int value = (int) typedValue.toLocal(); if (vector instanceof TimeMicroVector) { ((TimeMicroVector) vector).setSafe(index, value); diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimestampAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimestampAvaticaParameterConverter.java index 3ded14d044073..286846cc609c4 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimestampAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimestampAvaticaParameterConverter.java @@ -37,7 +37,7 @@ public TimestampAvaticaParameterConverter(ArrowType.Timestamp type) { } @Override - public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { // FIXME: how should we handle TZ? Do we need to convert the value to the TZ on the vector? long value = (long) typedValue.toLocal(); if (vector instanceof TimeStampSecVector) { diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/Utf8AvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/Utf8AvaticaParameterConverter.java index 898a2de64276f..eff912ff8a01d 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/Utf8AvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/Utf8AvaticaParameterConverter.java @@ -31,7 +31,7 @@ public Utf8AvaticaParameterConverter(ArrowType.Utf8 type) { } @Override - public boolean setParameter(FieldVector vector, TypedValue typedValue, int index) { + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { Object value = typedValue.toLocal(); if (vector instanceof VarCharVector) { ((VarCharVector) vector).setSafe(index, new Text((String) value)); diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java index b87708648c37b..6c0ba37bec8bb 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java @@ -119,7 +119,7 @@ private BinderVisitor(FieldVector vector, TypedValue value, int index) { @Override public Boolean visit(ArrowType.Null type) { - return new NullAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + return new NullAvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } @Override @@ -154,72 +154,72 @@ public Boolean visit(ArrowType.Map type) { @Override public Boolean visit(ArrowType.Int type) { - return new IntAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + return new IntAvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } @Override public Boolean visit(ArrowType.FloatingPoint type) { - return new FloatingPointAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + return new FloatingPointAvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } @Override public Boolean visit(ArrowType.Utf8 type) { - return new Utf8AvaticaParameterConverter(type).setParameter(vector, typedValue, index); + return new Utf8AvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } @Override public Boolean visit(ArrowType.LargeUtf8 type) { - return new LargeUtf8AvaticaParameterConverter(type).setParameter(vector, typedValue, index); + return new LargeUtf8AvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } @Override public Boolean visit(ArrowType.Binary type) { - return new BinaryAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + return new BinaryAvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } @Override public Boolean visit(ArrowType.LargeBinary type) { - return new LargeBinaryAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + return new LargeBinaryAvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } @Override public Boolean visit(ArrowType.FixedSizeBinary type) { - return new FixedSizeBinaryAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + return new FixedSizeBinaryAvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } @Override public Boolean visit(ArrowType.Bool type) { - return new BoolAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + return new BoolAvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } @Override public Boolean visit(ArrowType.Decimal type) { - return new DecimalAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + return new DecimalAvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } @Override public Boolean visit(ArrowType.Date type) { - return new DateAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + return new DateAvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } @Override public Boolean visit(ArrowType.Time type) { - return new TimeAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + return new TimeAvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } @Override public Boolean visit(ArrowType.Timestamp type) { - return new TimestampAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + return new TimestampAvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } @Override public Boolean visit(ArrowType.Interval type) { - return new IntervalAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + return new IntervalAvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } @Override public Boolean visit(ArrowType.Duration type) { - return new DurationAvaticaParameterConverter(type).setParameter(vector, typedValue, index); + return new DurationAvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } } From 3b44078aeb4258cc6a48d6ffc10b0b4ae2990189 Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Mon, 30 Oct 2023 18:06:40 +0000 Subject: [PATCH 15/21] . --- .../java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java index 68784ad1eedf8..e3c4363356229 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java @@ -137,7 +137,9 @@ public static void setOnColumnMetaDataBuilder(final Builder builder, * @return list of {@link AvaticaParameter}. */ public static List convertArrowFieldsToAvaticaParameters(final List fields) { - return fields.stream().map( field -> field.getType().accept(new ConverterVisitor(field))).collect(Collectors.toList()); + return fields.stream() + .map(field -> field.getType().accept(new ConverterVisitor(field))) + .collect(Collectors.toList()); } private static class ConverterVisitor implements ArrowType.ArrowTypeVisitor { From d3244e6d2607cc762649f3de35baae90e476cdb1 Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Mon, 30 Oct 2023 18:32:40 +0000 Subject: [PATCH 16/21] moar formatting --- .../impl/DateAvaticaParameterConverter.java | 3 +-- .../converter/impl/IntAvaticaParameterConverter.java | 5 ++++- .../impl/IntervalAvaticaParameterConverter.java | 12 ++++++------ .../impl/NullAvaticaParameterConverter.java | 2 +- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DateAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DateAvaticaParameterConverter.java index 8807fc65d4439..b658644dddd6e 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DateAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DateAvaticaParameterConverter.java @@ -40,8 +40,7 @@ public boolean bindParameter(FieldVector vector, TypedValue typedValue, int inde ((DateDayVector) vector).setSafe(index, (int) value); return true; } - return false; - + return false; } @Override diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntAvaticaParameterConverter.java index 911f53a49b42c..31cd31e54027a 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntAvaticaParameterConverter.java @@ -31,8 +31,11 @@ import org.apache.calcite.avatica.AvaticaParameter; import org.apache.calcite.avatica.remote.TypedValue; +/** + * AvaticaParameterConverter for Int Arrow types. + */ public class IntAvaticaParameterConverter extends BaseAvaticaParameterConverter { - final private ArrowType.Int type; + private final ArrowType.Int type; public IntAvaticaParameterConverter(ArrowType.Int type) { this.type = type; diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntervalAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntervalAvaticaParameterConverter.java index 416dc33a2e494..78e497568978d 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntervalAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntervalAvaticaParameterConverter.java @@ -30,12 +30,12 @@ public IntervalAvaticaParameterConverter(ArrowType.Interval type) { @Override public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { -// Object value = typedValue.toLocal(); -// if (vector instanceof IntervalDayVector) { -// ((IntervalDayVector) vector).setSafe(index, () value); -// } else if (vector instanceof IntervalYearVector) { -// ((IntervalYearVector) vector).setSafe(index, () value); -// } + // Object value = typedValue.toLocal(); + // if (vector instanceof IntervalDayVector) { + // ((IntervalDayVector) vector).setSafe(index, () value); + // } else if (vector instanceof IntervalYearVector) { + // ((IntervalYearVector) vector).setSafe(index, () value); + // } return false; } diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/NullAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/NullAvaticaParameterConverter.java index d64dd4195af9e..0ac26b7a59161 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/NullAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/NullAvaticaParameterConverter.java @@ -33,7 +33,7 @@ public NullAvaticaParameterConverter(ArrowType.Null type) { public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { Object value = typedValue.toLocal(); if (vector instanceof NullVector) { - if (value != null) throw new RuntimeException("Can't set non-null value on NullVector"); + if (value != null) { throw new RuntimeException("Can't set non-null value on NullVector"); } vector.setNull(index); } return false; From 2b136a78c2d122c0a3a9d1874de14b88b8dd7772 Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Mon, 30 Oct 2023 18:42:24 +0000 Subject: [PATCH 17/21] docstrings and reword exceptions --- .../converter/impl/BinaryAvaticaParameterConverter.java | 3 +++ .../converter/impl/BoolAvaticaParameterConverter.java | 3 +++ .../converter/impl/DateAvaticaParameterConverter.java | 3 +++ .../converter/impl/DecimalAvaticaParameterConverter.java | 3 +++ .../impl/DurationAvaticaParameterConverter.java | 3 +++ .../impl/FixedSizeBinaryAvaticaParameterConverter.java | 3 +++ .../impl/FloatingPointAvaticaParameterConverter.java | 3 +++ .../impl/IntervalAvaticaParameterConverter.java | 3 +++ .../impl/LargeBinaryAvaticaParameterConverter.java | 3 +++ .../impl/LargeUtf8AvaticaParameterConverter.java | 3 +++ .../converter/impl/NullAvaticaParameterConverter.java | 3 +++ .../converter/impl/TimeAvaticaParameterConverter.java | 3 +++ .../impl/TimestampAvaticaParameterConverter.java | 3 +++ .../converter/impl/Utf8AvaticaParameterConverter.java | 3 +++ .../arrow/driver/jdbc/utils/AvaticaParameterBinder.java | 9 ++++----- 15 files changed, 46 insertions(+), 5 deletions(-) diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BinaryAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BinaryAvaticaParameterConverter.java index b8a912073a8d1..a5e30a5ff1544 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BinaryAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BinaryAvaticaParameterConverter.java @@ -24,6 +24,9 @@ import org.apache.calcite.avatica.AvaticaParameter; import org.apache.calcite.avatica.remote.TypedValue; +/** + * AvaticaParameterConverter for Binary Arrow types. + */ public class BinaryAvaticaParameterConverter extends BaseAvaticaParameterConverter { public BinaryAvaticaParameterConverter(ArrowType.Binary type) { diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BoolAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BoolAvaticaParameterConverter.java index c84506878bc84..00714376feec4 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BoolAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BoolAvaticaParameterConverter.java @@ -24,6 +24,9 @@ import org.apache.calcite.avatica.AvaticaParameter; import org.apache.calcite.avatica.remote.TypedValue; +/** + * AvaticaParameterConverter for Bool Arrow types. + */ public class BoolAvaticaParameterConverter extends BaseAvaticaParameterConverter { public BoolAvaticaParameterConverter(ArrowType.Bool type) { diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DateAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DateAvaticaParameterConverter.java index b658644dddd6e..d6a68e2d9f17e 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DateAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DateAvaticaParameterConverter.java @@ -25,6 +25,9 @@ import org.apache.calcite.avatica.AvaticaParameter; import org.apache.calcite.avatica.remote.TypedValue; +/** + * AvaticaParameterConverter for Date Arrow types. + */ public class DateAvaticaParameterConverter extends BaseAvaticaParameterConverter { public DateAvaticaParameterConverter(ArrowType.Date type) { diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DecimalAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DecimalAvaticaParameterConverter.java index ae8b379cd9f38..844a41110caa4 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DecimalAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DecimalAvaticaParameterConverter.java @@ -26,6 +26,9 @@ import org.apache.calcite.avatica.AvaticaParameter; import org.apache.calcite.avatica.remote.TypedValue; +/** + * AvaticaParameterConverter for Decimal Arrow types. + */ public class DecimalAvaticaParameterConverter extends BaseAvaticaParameterConverter { public DecimalAvaticaParameterConverter(ArrowType.Decimal type) { diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DurationAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DurationAvaticaParameterConverter.java index aa0dda37622ab..89f2fc1d5c12f 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DurationAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DurationAvaticaParameterConverter.java @@ -23,6 +23,9 @@ import org.apache.calcite.avatica.AvaticaParameter; import org.apache.calcite.avatica.remote.TypedValue; +/** + * AvaticaParameterConverter for Duration Arrow types. + */ public class DurationAvaticaParameterConverter extends BaseAvaticaParameterConverter { public DurationAvaticaParameterConverter(ArrowType.Duration type) { diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FixedSizeBinaryAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FixedSizeBinaryAvaticaParameterConverter.java index 6d79c3ed96459..c9d7d0a91e480 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FixedSizeBinaryAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FixedSizeBinaryAvaticaParameterConverter.java @@ -24,6 +24,9 @@ import org.apache.calcite.avatica.AvaticaParameter; import org.apache.calcite.avatica.remote.TypedValue; +/** + * AvaticaParameterConverter for FixedSizeBinary Arrow types. + */ public class FixedSizeBinaryAvaticaParameterConverter extends BaseAvaticaParameterConverter { public FixedSizeBinaryAvaticaParameterConverter(ArrowType.FixedSizeBinary type) { diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FloatingPointAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FloatingPointAvaticaParameterConverter.java index dd84c611a89b3..5d222f8130feb 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FloatingPointAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FloatingPointAvaticaParameterConverter.java @@ -25,6 +25,9 @@ import org.apache.calcite.avatica.AvaticaParameter; import org.apache.calcite.avatica.remote.TypedValue; +/** + * AvaticaParameterConverter for FloatingPoint Arrow types. + */ public class FloatingPointAvaticaParameterConverter extends BaseAvaticaParameterConverter { public FloatingPointAvaticaParameterConverter(ArrowType.FloatingPoint type) { diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntervalAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntervalAvaticaParameterConverter.java index 78e497568978d..724275d51091e 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntervalAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntervalAvaticaParameterConverter.java @@ -23,6 +23,9 @@ import org.apache.calcite.avatica.AvaticaParameter; import org.apache.calcite.avatica.remote.TypedValue; +/** + * AvaticaParameterConverter for Interval Arrow types. + */ public class IntervalAvaticaParameterConverter extends BaseAvaticaParameterConverter { public IntervalAvaticaParameterConverter(ArrowType.Interval type) { diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeBinaryAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeBinaryAvaticaParameterConverter.java index 4ef80293f40e2..55828f3be85d9 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeBinaryAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeBinaryAvaticaParameterConverter.java @@ -24,6 +24,9 @@ import org.apache.calcite.avatica.AvaticaParameter; import org.apache.calcite.avatica.remote.TypedValue; +/** + * AvaticaParameterConverter for LargeBinary Arrow types. + */ public class LargeBinaryAvaticaParameterConverter extends BaseAvaticaParameterConverter { public LargeBinaryAvaticaParameterConverter(ArrowType.LargeBinary type) { diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeUtf8AvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeUtf8AvaticaParameterConverter.java index 01df472eac093..2d51cebd6e20f 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeUtf8AvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeUtf8AvaticaParameterConverter.java @@ -25,6 +25,9 @@ import org.apache.calcite.avatica.AvaticaParameter; import org.apache.calcite.avatica.remote.TypedValue; +/** + * AvaticaParameterConverter for LargeUtf8 Arrow types. + */ public class LargeUtf8AvaticaParameterConverter extends BaseAvaticaParameterConverter { public LargeUtf8AvaticaParameterConverter(ArrowType.LargeUtf8 type) { diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/NullAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/NullAvaticaParameterConverter.java index 0ac26b7a59161..e2c184fb11a09 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/NullAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/NullAvaticaParameterConverter.java @@ -24,6 +24,9 @@ import org.apache.calcite.avatica.AvaticaParameter; import org.apache.calcite.avatica.remote.TypedValue; +/** + * AvaticaParameterConverter for Null Arrow types. + */ public class NullAvaticaParameterConverter extends BaseAvaticaParameterConverter { public NullAvaticaParameterConverter(ArrowType.Null type) { diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimeAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimeAvaticaParameterConverter.java index d835b8df7ea9c..c6b79537fd435 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimeAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimeAvaticaParameterConverter.java @@ -27,6 +27,9 @@ import org.apache.calcite.avatica.AvaticaParameter; import org.apache.calcite.avatica.remote.TypedValue; +/** + * AvaticaParameterConverter for Time Arrow types. + */ public class TimeAvaticaParameterConverter extends BaseAvaticaParameterConverter { public TimeAvaticaParameterConverter(ArrowType.Time type) { diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimestampAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimestampAvaticaParameterConverter.java index 286846cc609c4..3c1940b75cfa7 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimestampAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/TimestampAvaticaParameterConverter.java @@ -31,6 +31,9 @@ import org.apache.calcite.avatica.AvaticaParameter; import org.apache.calcite.avatica.remote.TypedValue; +/** + * AvaticaParameterConverter for Timestamp Arrow types. + */ public class TimestampAvaticaParameterConverter extends BaseAvaticaParameterConverter { public TimestampAvaticaParameterConverter(ArrowType.Timestamp type) { diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/Utf8AvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/Utf8AvaticaParameterConverter.java index eff912ff8a01d..ea9636c892c2f 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/Utf8AvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/Utf8AvaticaParameterConverter.java @@ -25,6 +25,9 @@ import org.apache.calcite.avatica.AvaticaParameter; import org.apache.calcite.avatica.remote.TypedValue; +/** + * AvaticaParameterConverter for Utf8 Arrow types. + */ public class Utf8AvaticaParameterConverter extends BaseAvaticaParameterConverter { public Utf8AvaticaParameterConverter(ArrowType.Utf8 type) { diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java index 6c0ba37bec8bb..5ea9d849bd236 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java @@ -97,12 +97,13 @@ public void bind(List typedValues, int index) { private void bind(FieldVector vector, TypedValue typedValue, int index) { try { if (!vector.getField().getType().accept(new BinderVisitor(vector, typedValue, index))) { - throw new UnsupportedOperationException( + throw new RuntimeException( String.format("Binding to vector type %s is not yet supported", vector.getClass())); } } catch (ClassCastException e) { - throw new RuntimeException(String.format("Value of type %s is not compatible with Arrow type %s", - typedValue.type, vector.getField().getType())); + throw new RuntimeException( + String.format("Binding value of type %s is not yet supported for expected Arrow type %s", + typedValue.type, vector.getField().getType())); } } @@ -224,5 +225,3 @@ public Boolean visit(ArrowType.Duration type) { } } - - From 7d4abbb79d177d8f9884fbcae8fe63a8a8df73de Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Mon, 30 Oct 2023 19:21:53 +0000 Subject: [PATCH 18/21] Last docstring --- .../jdbc/converter/impl/BaseAvaticaParameterConverter.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BaseAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BaseAvaticaParameterConverter.java index 30c380f8a6642..f5cf8358b7a14 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BaseAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BaseAvaticaParameterConverter.java @@ -24,6 +24,10 @@ import org.apache.calcite.avatica.AvaticaParameter; import org.apache.calcite.avatica.SqlType; +/** + * Base AvaticaParameterConverter with a generic createParameter method that can be used by most + * Arrow types. + */ abstract class BaseAvaticaParameterConverter implements AvaticaParameterConverter { protected AvaticaParameter createParameter(Field field, boolean signed) { final String name = field.getName(); From af4f4cc873955c5d0864a4bfde5784ed3cb25b97 Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Mon, 30 Oct 2023 20:29:12 +0000 Subject: [PATCH 19/21] Add test for batched params --- .../ArrowFlightPreparedStatementTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java b/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java index 2f3f27da961e8..b19f049544ada 100644 --- a/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java +++ b/java/flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightPreparedStatementTest.java @@ -25,6 +25,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Arrays; import java.util.Collections; import org.apache.arrow.driver.jdbc.utils.CoreMockedSqlProducers; @@ -166,4 +167,24 @@ public void testUpdateQueryWithParameters() throws SQLException { assertEquals(42, updated); } } + + @Test + public void testUpdateQueryWithBatchedParameters() throws SQLException { + String query = "Fake update with batched parameters"; + PRODUCER.addUpdateQuery(query, /*updatedRows*/42); + PRODUCER.addExpectedParameters(query, + new Schema(Collections.singletonList(Field.nullable("", ArrowType.Utf8.INSTANCE))), + Arrays.asList( + Collections.singletonList(new Text("foo".getBytes(StandardCharsets.UTF_8))), + Collections.singletonList(new Text("bar".getBytes(StandardCharsets.UTF_8))))); + try (final PreparedStatement stmt = connection.prepareStatement(query)) { + // TODO: make sure this is validated on the server too + stmt.setString(1, "foo"); + stmt.addBatch(); + stmt.setString(1, "bar"); + stmt.addBatch(); + int[] updated = stmt.executeBatch(); + assertEquals(42, updated[0]); + } + } } From facc0dc97f367a97ce2b2cf34a4ebb4d90ef3614 Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Mon, 30 Oct 2023 21:06:38 +0000 Subject: [PATCH 20/21] Add converter for missing types --- ...ixedSizeListAvaticaParameterConverter.java | 43 +++++++++++++++++++ .../LargeListAvaticaParameterConverter.java | 43 +++++++++++++++++++ .../impl/ListAvaticaParameterConverter.java | 43 +++++++++++++++++++ .../impl/MapAvaticaParameterConverter.java | 43 +++++++++++++++++++ .../impl/StructAvaticaParameterConverter.java | 43 +++++++++++++++++++ .../impl/UnionAvaticaParameterConverter.java | 43 +++++++++++++++++++ .../jdbc/utils/AvaticaParameterBinder.java | 18 +++++--- .../arrow/driver/jdbc/utils/ConvertUtils.java | 22 +++++++--- 8 files changed, 286 insertions(+), 12 deletions(-) create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FixedSizeListAvaticaParameterConverter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeListAvaticaParameterConverter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/ListAvaticaParameterConverter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/MapAvaticaParameterConverter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/StructAvaticaParameterConverter.java create mode 100644 java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/UnionAvaticaParameterConverter.java diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FixedSizeListAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FixedSizeListAvaticaParameterConverter.java new file mode 100644 index 0000000000000..60231a2460286 --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FixedSizeListAvaticaParameterConverter.java @@ -0,0 +1,43 @@ +/* + * 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.driver.jdbc.converter.impl; + +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +/** + * AvaticaParameterConverter for FixedSizeList Arrow types. + */ +public class FixedSizeListAvaticaParameterConverter extends BaseAvaticaParameterConverter { + + public FixedSizeListAvaticaParameterConverter(ArrowType.FixedSizeList type) { + } + + @Override + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { + return false; + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, false); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeListAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeListAvaticaParameterConverter.java new file mode 100644 index 0000000000000..6ef6920474860 --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeListAvaticaParameterConverter.java @@ -0,0 +1,43 @@ +/* + * 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.driver.jdbc.converter.impl; + +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +/** + * AvaticaParameterConverter for LargeList Arrow types. + */ +public class LargeListAvaticaParameterConverter extends BaseAvaticaParameterConverter { + + public LargeListAvaticaParameterConverter(ArrowType.LargeList type) { + } + + @Override + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { + return false; + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, false); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/ListAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/ListAvaticaParameterConverter.java new file mode 100644 index 0000000000000..aec59cb4d428e --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/ListAvaticaParameterConverter.java @@ -0,0 +1,43 @@ +/* + * 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.driver.jdbc.converter.impl; + +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +/** + * AvaticaParameterConverter for List Arrow types. + */ +public class ListAvaticaParameterConverter extends BaseAvaticaParameterConverter { + + public ListAvaticaParameterConverter(ArrowType.List type) { + } + + @Override + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { + return false; + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, false); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/MapAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/MapAvaticaParameterConverter.java new file mode 100644 index 0000000000000..feac3794d222b --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/MapAvaticaParameterConverter.java @@ -0,0 +1,43 @@ +/* + * 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.driver.jdbc.converter.impl; + +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +/** + * AvaticaParameterConverter for Map Arrow types. + */ +public class MapAvaticaParameterConverter extends BaseAvaticaParameterConverter { + + public MapAvaticaParameterConverter(ArrowType.Map type) { + } + + @Override + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { + return false; + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, false); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/StructAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/StructAvaticaParameterConverter.java new file mode 100644 index 0000000000000..5dfe923cb516e --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/StructAvaticaParameterConverter.java @@ -0,0 +1,43 @@ +/* + * 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.driver.jdbc.converter.impl; + +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +/** + * AvaticaParameterConverter for Struct Arrow types. + */ +public class StructAvaticaParameterConverter extends BaseAvaticaParameterConverter { + + public StructAvaticaParameterConverter(ArrowType.Struct type) { + } + + @Override + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { + return false; + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, false); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/UnionAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/UnionAvaticaParameterConverter.java new file mode 100644 index 0000000000000..6b171e685579a --- /dev/null +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/UnionAvaticaParameterConverter.java @@ -0,0 +1,43 @@ +/* + * 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.driver.jdbc.converter.impl; + +import org.apache.arrow.vector.FieldVector; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.calcite.avatica.AvaticaParameter; +import org.apache.calcite.avatica.remote.TypedValue; + +/** + * AvaticaParameterConverter for Union Arrow types. + */ +public class UnionAvaticaParameterConverter extends BaseAvaticaParameterConverter { + + public UnionAvaticaParameterConverter(ArrowType.Union type) { + } + + @Override + public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { + return false; + } + + @Override + public AvaticaParameter createParameter(Field field) { + return createParameter(field, false); + } +} diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java index 5ea9d849bd236..c5be4697db7c5 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java @@ -26,14 +26,20 @@ import org.apache.arrow.driver.jdbc.converter.impl.DecimalAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.DurationAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.FixedSizeBinaryAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.FixedSizeListAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.FloatingPointAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.IntAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.IntervalAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.LargeBinaryAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.LargeListAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.LargeUtf8AvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.ListAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.MapAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.NullAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.StructAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.TimeAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.TimestampAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.UnionAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.Utf8AvaticaParameterConverter; import org.apache.arrow.memory.BufferAllocator; import org.apache.arrow.vector.FieldVector; @@ -125,32 +131,32 @@ public Boolean visit(ArrowType.Null type) { @Override public Boolean visit(ArrowType.Struct type) { - return false; + return new StructAvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } @Override public Boolean visit(ArrowType.List type) { - return false; + return new ListAvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } @Override public Boolean visit(ArrowType.LargeList type) { - return false; + return new LargeListAvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } @Override public Boolean visit(ArrowType.FixedSizeList type) { - return false; + return new FixedSizeListAvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } @Override public Boolean visit(ArrowType.Union type) { - return false; + return new UnionAvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } @Override public Boolean visit(ArrowType.Map type) { - return false; + return new MapAvaticaParameterConverter(type).bindParameter(vector, typedValue, index); } @Override diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java index e3c4363356229..b21b03340e9f9 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/ConvertUtils.java @@ -28,14 +28,20 @@ import org.apache.arrow.driver.jdbc.converter.impl.DecimalAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.DurationAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.FixedSizeBinaryAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.FixedSizeListAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.FloatingPointAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.IntAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.IntervalAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.LargeBinaryAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.LargeListAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.LargeUtf8AvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.ListAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.MapAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.NullAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.StructAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.TimeAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.TimestampAvaticaParameterConverter; +import org.apache.arrow.driver.jdbc.converter.impl.UnionAvaticaParameterConverter; import org.apache.arrow.driver.jdbc.converter.impl.Utf8AvaticaParameterConverter; import org.apache.arrow.flight.sql.FlightSqlColumnMetadata; import org.apache.arrow.vector.types.pojo.ArrowType; @@ -156,32 +162,36 @@ public AvaticaParameter visit(ArrowType.Null type) { @Override public AvaticaParameter visit(ArrowType.Struct type) { - throw new UnsupportedOperationException(); + return new StructAvaticaParameterConverter(type).createParameter(field); } @Override public AvaticaParameter visit(ArrowType.List type) { - throw new UnsupportedOperationException(); + return new ListAvaticaParameterConverter(type).createParameter(field); + } @Override public AvaticaParameter visit(ArrowType.LargeList type) { - throw new UnsupportedOperationException(); + return new LargeListAvaticaParameterConverter(type).createParameter(field); + } @Override public AvaticaParameter visit(ArrowType.FixedSizeList type) { - throw new UnsupportedOperationException(); + return new FixedSizeListAvaticaParameterConverter(type).createParameter(field); + } @Override public AvaticaParameter visit(ArrowType.Union type) { - throw new UnsupportedOperationException(); + return new UnionAvaticaParameterConverter(type).createParameter(field); + } @Override public AvaticaParameter visit(ArrowType.Map type) { - throw new UnsupportedOperationException(); + return new MapAvaticaParameterConverter(type).createParameter(field); } @Override From ea49366b4f33d0c910a7bb495e1bae386012193e Mon Sep 17 00:00:00 2001 From: Diego Fernandez Date: Wed, 1 Nov 2023 04:01:38 +0000 Subject: [PATCH 21/21] Improve casting for TypedValues --- .../impl/BinaryAvaticaParameterConverter.java | 4 +-- .../impl/BoolAvaticaParameterConverter.java | 4 +-- .../impl/DateAvaticaParameterConverter.java | 6 ++-- .../DecimalAvaticaParameterConverter.java | 4 +-- ...edSizeBinaryAvaticaParameterConverter.java | 4 +-- ...loatingPointAvaticaParameterConverter.java | 6 ++-- .../impl/IntAvaticaParameterConverter.java | 28 ++++++------------- .../LargeBinaryAvaticaParameterConverter.java | 4 +-- .../LargeUtf8AvaticaParameterConverter.java | 4 +-- .../impl/Utf8AvaticaParameterConverter.java | 4 +-- 10 files changed, 29 insertions(+), 39 deletions(-) diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BinaryAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BinaryAvaticaParameterConverter.java index a5e30a5ff1544..d244848955e52 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BinaryAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BinaryAvaticaParameterConverter.java @@ -34,9 +34,9 @@ public BinaryAvaticaParameterConverter(ArrowType.Binary type) { @Override public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { - Object value = typedValue.toLocal(); + byte[] value = (byte[]) typedValue.toJdbc(null); if (vector instanceof VarBinaryVector) { - ((VarBinaryVector) vector).setSafe(index, (byte[]) value); + ((VarBinaryVector) vector).setSafe(index, value); return true; } return false; diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BoolAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BoolAvaticaParameterConverter.java index 00714376feec4..6725154d03c25 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BoolAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BoolAvaticaParameterConverter.java @@ -34,9 +34,9 @@ public BoolAvaticaParameterConverter(ArrowType.Bool type) { @Override public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { - Object value = typedValue.toLocal(); + boolean value = (boolean) typedValue.toLocal(); if (vector instanceof BitVector) { - ((BitVector) vector).setSafe(index, (int) value); + ((BitVector) vector).setSafe(index, value ? 1 : 0); return true; } return false; diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DateAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DateAvaticaParameterConverter.java index d6a68e2d9f17e..0da1dabe43721 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DateAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DateAvaticaParameterConverter.java @@ -35,12 +35,12 @@ public DateAvaticaParameterConverter(ArrowType.Date type) { @Override public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { - Object value = typedValue.toLocal(); + int value = (int) typedValue.toLocal(); if (vector instanceof DateMilliVector) { - ((DateMilliVector) vector).setSafe(index, (int) value); + ((DateMilliVector) vector).setSafe(index, value); return true; } else if (vector instanceof DateDayVector) { - ((DateDayVector) vector).setSafe(index, (int) value); + ((DateDayVector) vector).setSafe(index, value); return true; } return false; diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DecimalAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DecimalAvaticaParameterConverter.java index 844a41110caa4..fad43e2e06a76 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DecimalAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/DecimalAvaticaParameterConverter.java @@ -36,9 +36,9 @@ public DecimalAvaticaParameterConverter(ArrowType.Decimal type) { @Override public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { - Object value = typedValue.toLocal(); + BigDecimal value = (BigDecimal) typedValue.toLocal(); if (vector instanceof DecimalVector) { - ((DecimalVector) vector).setSafe(index, (BigDecimal) value); + ((DecimalVector) vector).setSafe(index, value); return true; } return false; diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FixedSizeBinaryAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FixedSizeBinaryAvaticaParameterConverter.java index c9d7d0a91e480..a90434f695ac3 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FixedSizeBinaryAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FixedSizeBinaryAvaticaParameterConverter.java @@ -34,9 +34,9 @@ public FixedSizeBinaryAvaticaParameterConverter(ArrowType.FixedSizeBinary type) @Override public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { - Object value = typedValue.toLocal(); + byte[] value = (byte[]) typedValue.toJdbc(null); if (vector instanceof FixedSizeBinaryVector) { - ((FixedSizeBinaryVector) vector).setSafe(index, (byte[]) value); + ((FixedSizeBinaryVector) vector).setSafe(index, value); return true; } return false; diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FloatingPointAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FloatingPointAvaticaParameterConverter.java index 5d222f8130feb..9f305a2b6f20d 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FloatingPointAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/FloatingPointAvaticaParameterConverter.java @@ -35,12 +35,12 @@ public FloatingPointAvaticaParameterConverter(ArrowType.FloatingPoint type) { @Override public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { - Object value = typedValue.toLocal(); + Number value = (Number) typedValue.value; if (vector instanceof Float4Vector) { - ((Float4Vector) vector).setSafe(index, (float) value); + ((Float4Vector) vector).setSafe(index, value.floatValue()); return true; } else if (vector instanceof Float8Vector) { - ((Float8Vector) vector).setSafe(index, (double) value); + ((Float8Vector) vector).setSafe(index, value.doubleValue()); return true; } return false; diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntAvaticaParameterConverter.java index 31cd31e54027a..6684e8d32c9a9 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/IntAvaticaParameterConverter.java @@ -43,40 +43,30 @@ public IntAvaticaParameterConverter(ArrowType.Int type) { @Override public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { - Object value = typedValue.toLocal(); + Number value = (Number) typedValue.value; if (vector instanceof TinyIntVector) { - ((TinyIntVector) vector).setSafe(index, (int) value); + ((TinyIntVector) vector).setSafe(index, value.intValue()); return true; } else if (vector instanceof SmallIntVector) { - ((SmallIntVector) vector).setSafe(index, (int) value); + ((SmallIntVector) vector).setSafe(index, value.intValue()); return true; } else if (vector instanceof IntVector) { - ((IntVector) vector).setSafe(index, (int) value); + ((IntVector) vector).setSafe(index, value.intValue()); return true; } else if (vector instanceof BigIntVector) { - BigIntVector longVec = (BigIntVector) vector; - if (value instanceof Long) { - longVec.setSafe(index, (long) value); - } else { - longVec.setSafe(index, (int) value); - } + ((BigIntVector) vector).setSafe(index, value.longValue()); return true; } else if (vector instanceof UInt1Vector) { - ((UInt1Vector) vector).setSafe(index, (int) value); + ((UInt1Vector) vector).setSafe(index, value.intValue()); return true; } else if (vector instanceof UInt2Vector) { - ((UInt2Vector) vector).setSafe(index, (int) value); + ((UInt2Vector) vector).setSafe(index, value.intValue()); return true; } else if (vector instanceof UInt4Vector) { - ((UInt4Vector) vector).setSafe(index, (int) value); + ((UInt4Vector) vector).setSafe(index, value.intValue()); return true; } else if (vector instanceof UInt8Vector) { - UInt8Vector longVec = (UInt8Vector) vector; - if (value instanceof Long) { - longVec.setSafe(index, (long) value); - } else { - longVec.setSafe(index, (int) value); - } + ((UInt8Vector) vector).setSafe(index, value.longValue()); return true; } return false; diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeBinaryAvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeBinaryAvaticaParameterConverter.java index 55828f3be85d9..133ec2072d583 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeBinaryAvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeBinaryAvaticaParameterConverter.java @@ -34,9 +34,9 @@ public LargeBinaryAvaticaParameterConverter(ArrowType.LargeBinary type) { @Override public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { - Object value = typedValue.toLocal(); + byte[] value = (byte[]) typedValue.toJdbc(null); if (vector instanceof LargeVarBinaryVector) { - ((LargeVarBinaryVector) vector).setSafe(index, (byte[]) value); + ((LargeVarBinaryVector) vector).setSafe(index, value); return true; } return false; diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeUtf8AvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeUtf8AvaticaParameterConverter.java index 2d51cebd6e20f..d412ab007ac67 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeUtf8AvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/LargeUtf8AvaticaParameterConverter.java @@ -35,9 +35,9 @@ public LargeUtf8AvaticaParameterConverter(ArrowType.LargeUtf8 type) { @Override public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { - Object value = typedValue.toLocal(); + String value = (String) typedValue.toLocal(); if (vector instanceof LargeVarCharVector) { - ((LargeVarCharVector) vector).setSafe(index, new Text((String) value)); + ((LargeVarCharVector) vector).setSafe(index, new Text(value)); return true; } return false; diff --git a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/Utf8AvaticaParameterConverter.java b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/Utf8AvaticaParameterConverter.java index ea9636c892c2f..9223e5361d2d5 100644 --- a/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/Utf8AvaticaParameterConverter.java +++ b/java/flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/Utf8AvaticaParameterConverter.java @@ -35,9 +35,9 @@ public Utf8AvaticaParameterConverter(ArrowType.Utf8 type) { @Override public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) { - Object value = typedValue.toLocal(); + String value = (String) typedValue.toLocal(); if (vector instanceof VarCharVector) { - ((VarCharVector) vector).setSafe(index, new Text((String) value)); + ((VarCharVector) vector).setSafe(index, new Text(value)); return true; } return false;