Skip to content

Commit 76f3c1f

Browse files
authored
Merge branch 'main' into uuid-support
2 parents 446e52e + 2329174 commit 76f3c1f

File tree

14 files changed

+296
-14
lines changed

14 files changed

+296
-14
lines changed

flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/accessor/ArrowFlightJdbcAccessorFactory.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@
7070
import org.apache.arrow.vector.ValueVector;
7171
import org.apache.arrow.vector.VarBinaryVector;
7272
import org.apache.arrow.vector.VarCharVector;
73+
import org.apache.arrow.vector.ViewVarBinaryVector;
74+
import org.apache.arrow.vector.ViewVarCharVector;
7375
import org.apache.arrow.vector.complex.DenseUnionVector;
7476
import org.apache.arrow.vector.complex.FixedSizeListVector;
7577
import org.apache.arrow.vector.complex.LargeListVector;
@@ -132,6 +134,9 @@ public static ArrowFlightJdbcAccessor createAccessor(
132134
} else if (vector instanceof VarBinaryVector) {
133135
return new ArrowFlightJdbcBinaryVectorAccessor(
134136
(VarBinaryVector) vector, getCurrentRow, setCursorWasNull);
137+
} else if (vector instanceof ViewVarBinaryVector) {
138+
return new ArrowFlightJdbcBinaryVectorAccessor(
139+
(ViewVarBinaryVector) vector, getCurrentRow, setCursorWasNull);
135140
} else if (vector instanceof LargeVarBinaryVector) {
136141
return new ArrowFlightJdbcBinaryVectorAccessor(
137142
(LargeVarBinaryVector) vector, getCurrentRow, setCursorWasNull);
@@ -168,6 +173,9 @@ public static ArrowFlightJdbcAccessor createAccessor(
168173
} else if (vector instanceof LargeVarCharVector) {
169174
return new ArrowFlightJdbcVarCharVectorAccessor(
170175
(LargeVarCharVector) vector, getCurrentRow, setCursorWasNull);
176+
} else if (vector instanceof ViewVarCharVector) {
177+
return new ArrowFlightJdbcVarCharVectorAccessor(
178+
(ViewVarCharVector) vector, getCurrentRow, setCursorWasNull);
171179
} else if (vector instanceof DurationVector) {
172180
return new ArrowFlightJdbcDurationVectorAccessor(
173181
(DurationVector) vector, getCurrentRow, setCursorWasNull);

flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/accessor/impl/binary/ArrowFlightJdbcBinaryVectorAccessor.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.apache.arrow.vector.FixedSizeBinaryVector;
2828
import org.apache.arrow.vector.LargeVarBinaryVector;
2929
import org.apache.arrow.vector.VarBinaryVector;
30+
import org.apache.arrow.vector.ViewVarBinaryVector;
3031

3132
/**
3233
* Accessor for the Arrow types: {@link FixedSizeBinaryVector}, {@link VarBinaryVector} and {@link
@@ -61,6 +62,13 @@ public ArrowFlightJdbcBinaryVectorAccessor(
6162
this(vector::get, currentRowSupplier, setCursorWasNull);
6263
}
6364

65+
public ArrowFlightJdbcBinaryVectorAccessor(
66+
ViewVarBinaryVector vector,
67+
IntSupplier currentRowSupplier,
68+
ArrowFlightJdbcAccessorFactory.WasNullConsumer setCursorWasNull) {
69+
this(vector::get, currentRowSupplier, setCursorWasNull);
70+
}
71+
6472
private ArrowFlightJdbcBinaryVectorAccessor(
6573
ByteArrayGetter getter,
6674
IntSupplier currentRowSupplier,

flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/accessor/impl/text/ArrowFlightJdbcVarCharVectorAccessor.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.apache.arrow.driver.jdbc.utils.DateTimeUtils;
3636
import org.apache.arrow.vector.LargeVarCharVector;
3737
import org.apache.arrow.vector.VarCharVector;
38+
import org.apache.arrow.vector.ViewVarCharVector;
3839
import org.apache.arrow.vector.util.Text;
3940

4041
/** Accessor for the Arrow types: {@link VarCharVector} and {@link LargeVarCharVector}. */
@@ -62,6 +63,13 @@ public ArrowFlightJdbcVarCharVectorAccessor(
6263
this(vector::get, currentRowSupplier, setCursorWasNull);
6364
}
6465

66+
public ArrowFlightJdbcVarCharVectorAccessor(
67+
ViewVarCharVector vector,
68+
IntSupplier currentRowSupplier,
69+
ArrowFlightJdbcAccessorFactory.WasNullConsumer setCursorWasNull) {
70+
this(vector::get, currentRowSupplier, setCursorWasNull);
71+
}
72+
6573
ArrowFlightJdbcVarCharVectorAccessor(
6674
Getter getter,
6775
IntSupplier currentRowSupplier,

flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/client/ArrowFlightSqlClientHandler.java

Lines changed: 72 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -262,15 +262,85 @@ public FlightInfo getInfo(final String query) {
262262
@Override
263263
public void close() throws SQLException {
264264
if (catalog.isPresent()) {
265-
sqlClient.closeSession(new CloseSessionRequest(), getOptions());
265+
try {
266+
sqlClient.closeSession(new CloseSessionRequest(), getOptions());
267+
} catch (FlightRuntimeException fre) {
268+
handleBenignCloseException(
269+
fre, "Failed to close Flight SQL session.", "closing Flight SQL session");
270+
}
266271
}
267272
try {
268273
AutoCloseables.close(sqlClient);
274+
} catch (FlightRuntimeException fre) {
275+
handleBenignCloseException(
276+
fre, "Failed to clean up client resources.", "closing Flight SQL client");
269277
} catch (final Exception e) {
270278
throw new SQLException("Failed to clean up client resources.", e);
271279
}
272280
}
273281

282+
/**
283+
* Handles FlightRuntimeException during close operations, suppressing benign gRPC shutdown errors
284+
* while re-throwing genuine failures.
285+
*
286+
* @param fre the FlightRuntimeException to handle
287+
* @param sqlErrorMessage the SQLException message to use for genuine failures
288+
* @param operationDescription description of the operation for logging
289+
* @throws SQLException if the exception represents a genuine failure
290+
*/
291+
private void handleBenignCloseException(
292+
FlightRuntimeException fre, String sqlErrorMessage, String operationDescription)
293+
throws SQLException {
294+
if (isBenignCloseException(fre)) {
295+
logSuppressedCloseException(fre, operationDescription);
296+
} else {
297+
throw new SQLException(sqlErrorMessage, fre);
298+
}
299+
}
300+
301+
/**
302+
* Handles FlightRuntimeException during close operations, suppressing benign gRPC shutdown errors
303+
* while re-throwing genuine failures as FlightRuntimeException.
304+
*
305+
* @param fre the FlightRuntimeException to handle
306+
* @param operationDescription description of the operation for logging
307+
* @throws FlightRuntimeException if the exception represents a genuine failure
308+
*/
309+
private void handleBenignCloseException(FlightRuntimeException fre, String operationDescription)
310+
throws FlightRuntimeException {
311+
if (isBenignCloseException(fre)) {
312+
logSuppressedCloseException(fre, operationDescription);
313+
} else {
314+
throw fre;
315+
}
316+
}
317+
318+
/**
319+
* Determines if a FlightRuntimeException represents a benign close operation error that should be
320+
* suppressed.
321+
*
322+
* @param fre the FlightRuntimeException to check
323+
* @return true if the exception should be suppressed, false otherwise
324+
*/
325+
private boolean isBenignCloseException(FlightRuntimeException fre) {
326+
return fre.status().code().equals(FlightStatusCode.UNAVAILABLE)
327+
|| (fre.status().code().equals(FlightStatusCode.INTERNAL)
328+
&& fre.getMessage() != null
329+
&& fre.getMessage().contains("Connection closed after GOAWAY"));
330+
}
331+
332+
/**
333+
* Logs a suppressed close exception with appropriate level based on debug settings.
334+
*
335+
* @param fre the FlightRuntimeException being suppressed
336+
* @param operationDescription description of the operation for logging
337+
*/
338+
private void logSuppressedCloseException(
339+
FlightRuntimeException fre, String operationDescription) {
340+
// ARROW-17785 and GH-863: suppress exceptions caused by flaky gRPC layer during shutdown
341+
LOGGER.debug("Suppressed error {}", operationDescription, fre);
342+
}
343+
274344
/** A prepared statement handler. */
275345
public interface PreparedStatement extends AutoCloseable {
276346
/**
@@ -386,14 +456,7 @@ public void close() {
386456
try {
387457
preparedStatement.close(getOptions());
388458
} catch (FlightRuntimeException fre) {
389-
// ARROW-17785: suppress exceptions caused by flaky gRPC layer
390-
if (fre.status().code().equals(FlightStatusCode.UNAVAILABLE)
391-
|| (fre.status().code().equals(FlightStatusCode.INTERNAL)
392-
&& fre.getMessage().contains("Connection closed after GOAWAY"))) {
393-
LOGGER.warn("Supressed error closing PreparedStatement", fre);
394-
return;
395-
}
396-
throw fre;
459+
handleBenignCloseException(fre, "closing PreparedStatement");
397460
}
398461
}
399462
};

flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/BinaryViewAvaticaParameterConverter.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.apache.arrow.driver.jdbc.converter.impl;
1818

1919
import org.apache.arrow.vector.FieldVector;
20+
import org.apache.arrow.vector.ViewVarBinaryVector;
2021
import org.apache.arrow.vector.types.pojo.ArrowType;
2122
import org.apache.arrow.vector.types.pojo.Field;
2223
import org.apache.calcite.avatica.AvaticaParameter;
@@ -29,7 +30,12 @@ public BinaryViewAvaticaParameterConverter(ArrowType.BinaryView type) {}
2930

3031
@Override
3132
public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) {
32-
throw new UnsupportedOperationException("Not implemented");
33+
byte[] value = (byte[]) typedValue.toJdbc(null);
34+
if (vector instanceof ViewVarBinaryVector) {
35+
((ViewVarBinaryVector) vector).setSafe(index, value);
36+
return true;
37+
}
38+
return false;
3339
}
3440

3541
@Override

flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/converter/impl/Utf8ViewAvaticaParameterConverter.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
package org.apache.arrow.driver.jdbc.converter.impl;
1818

1919
import org.apache.arrow.vector.FieldVector;
20+
import org.apache.arrow.vector.ViewVarCharVector;
2021
import org.apache.arrow.vector.types.pojo.ArrowType;
2122
import org.apache.arrow.vector.types.pojo.Field;
23+
import org.apache.arrow.vector.util.Text;
2224
import org.apache.calcite.avatica.AvaticaParameter;
2325
import org.apache.calcite.avatica.remote.TypedValue;
2426

@@ -29,7 +31,12 @@ public Utf8ViewAvaticaParameterConverter(ArrowType.Utf8View type) {}
2931

3032
@Override
3133
public boolean bindParameter(FieldVector vector, TypedValue typedValue, int index) {
32-
throw new UnsupportedOperationException("Utf8View not supported");
34+
String value = (String) typedValue.toLocal();
35+
if (vector instanceof ViewVarCharVector) {
36+
((ViewVarCharVector) vector).setSafe(index, new Text(value));
37+
return true;
38+
}
39+
return false;
3340
}
3441

3542
@Override

flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/AvaticaParameterBinder.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.List;
2020
import org.apache.arrow.driver.jdbc.client.ArrowFlightSqlClientHandler.PreparedStatement;
2121
import org.apache.arrow.driver.jdbc.converter.impl.BinaryAvaticaParameterConverter;
22+
import org.apache.arrow.driver.jdbc.converter.impl.BinaryViewAvaticaParameterConverter;
2223
import org.apache.arrow.driver.jdbc.converter.impl.BoolAvaticaParameterConverter;
2324
import org.apache.arrow.driver.jdbc.converter.impl.DateAvaticaParameterConverter;
2425
import org.apache.arrow.driver.jdbc.converter.impl.DecimalAvaticaParameterConverter;
@@ -40,6 +41,7 @@
4041
import org.apache.arrow.driver.jdbc.converter.impl.UnionAvaticaParameterConverter;
4142
import org.apache.arrow.driver.jdbc.converter.impl.Utf8AvaticaParameterConverter;
4243
import org.apache.arrow.driver.jdbc.converter.impl.UuidAvaticaParameterConverter;
44+
import org.apache.arrow.driver.jdbc.converter.impl.Utf8ViewAvaticaParameterConverter;
4345
import org.apache.arrow.memory.BufferAllocator;
4446
import org.apache.arrow.vector.FieldVector;
4547
import org.apache.arrow.vector.VectorSchemaRoot;
@@ -212,7 +214,7 @@ public Boolean visit(ArrowType.Utf8 type) {
212214

213215
@Override
214216
public Boolean visit(ArrowType.Utf8View type) {
215-
throw new UnsupportedOperationException("Utf8View is unsupported");
217+
return new Utf8ViewAvaticaParameterConverter(type).bindParameter(vector, typedValue, index);
216218
}
217219

218220
@Override
@@ -227,7 +229,7 @@ public Boolean visit(ArrowType.Binary type) {
227229

228230
@Override
229231
public Boolean visit(ArrowType.BinaryView type) {
230-
throw new UnsupportedOperationException("BinaryView is unsupported");
232+
return new BinaryViewAvaticaParameterConverter(type).bindParameter(vector, typedValue, index);
231233
}
232234

233235
@Override

flight/flight-sql-jdbc-core/src/main/java/org/apache/arrow/driver/jdbc/utils/SqlTypes.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ public static int getSqlTypeIdFromArrowType(ArrowType arrowType) {
109109
}
110110
break;
111111
case Binary:
112+
case BinaryView:
112113
return Types.VARBINARY;
113114
case FixedSizeBinary:
114115
if (arrowType instanceof UuidType) {
@@ -118,6 +119,7 @@ public static int getSqlTypeIdFromArrowType(ArrowType arrowType) {
118119
case LargeBinary:
119120
return Types.LONGVARBINARY;
120121
case Utf8:
122+
case Utf8View:
121123
return Types.VARCHAR;
122124
case LargeUtf8:
123125
return Types.LONGVARCHAR;

flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/accessor/ArrowFlightJdbcAccessorFactoryTest.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
import org.apache.arrow.vector.LargeVarCharVector;
4949
import org.apache.arrow.vector.ValueVector;
5050
import org.apache.arrow.vector.VarCharVector;
51+
import org.apache.arrow.vector.ViewVarBinaryVector;
52+
import org.apache.arrow.vector.ViewVarCharVector;
5153
import org.apache.arrow.vector.complex.DenseUnionVector;
5254
import org.apache.arrow.vector.complex.MapVector;
5355
import org.apache.arrow.vector.complex.StructVector;
@@ -241,6 +243,18 @@ public void createAccessorForFixedSizeBinaryVector() {
241243
}
242244
}
243245

246+
@Test
247+
public void createAccessorForViewVarBinaryVector() {
248+
try (ValueVector valueVector =
249+
new ViewVarBinaryVector("", rootAllocatorTestExtension.getRootAllocator())) {
250+
ArrowFlightJdbcAccessor accessor =
251+
ArrowFlightJdbcAccessorFactory.createAccessor(
252+
valueVector, GET_CURRENT_ROW, (boolean wasNull) -> {});
253+
254+
assertTrue(accessor instanceof ArrowFlightJdbcBinaryVectorAccessor);
255+
}
256+
}
257+
244258
@Test
245259
public void createAccessorForTimeStampVector() {
246260
try (ValueVector valueVector = rootAllocatorTestExtension.createTimeStampMilliVector()) {
@@ -342,6 +356,18 @@ public void createAccessorForLargeVarCharVector() {
342356
}
343357
}
344358

359+
@Test
360+
public void createAccessorForViewVarCharVector() {
361+
try (ValueVector valueVector =
362+
new ViewVarCharVector("", rootAllocatorTestExtension.getRootAllocator())) {
363+
ArrowFlightJdbcAccessor accessor =
364+
ArrowFlightJdbcAccessorFactory.createAccessor(
365+
valueVector, GET_CURRENT_ROW, (boolean wasNull) -> {});
366+
367+
assertTrue(accessor instanceof ArrowFlightJdbcVarCharVectorAccessor);
368+
}
369+
}
370+
345371
@Test
346372
public void createAccessorForDurationVector() {
347373
try (ValueVector valueVector =

flight/flight-sql-jdbc-core/src/test/java/org/apache/arrow/driver/jdbc/accessor/impl/text/ArrowFlightJdbcVarCharVectorAccessorTest.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import static org.hamcrest.CoreMatchers.instanceOf;
2525
import static org.hamcrest.MatcherAssert.assertThat;
2626
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
27+
import static org.junit.jupiter.api.Assertions.assertEquals;
28+
import static org.junit.jupiter.api.Assertions.assertNull;
2729
import static org.junit.jupiter.api.Assertions.assertThrows;
2830
import static org.mockito.Mockito.when;
2931

@@ -46,6 +48,8 @@
4648
import org.apache.arrow.vector.DateMilliVector;
4749
import org.apache.arrow.vector.TimeMilliVector;
4850
import org.apache.arrow.vector.TimeStampVector;
51+
import org.apache.arrow.vector.VarCharVector;
52+
import org.apache.arrow.vector.ViewVarCharVector;
4953
import org.apache.arrow.vector.util.Text;
5054
import org.junit.jupiter.api.BeforeEach;
5155
import org.junit.jupiter.api.Test;
@@ -695,4 +699,26 @@ public void testShouldGetObjectClassReturnString() {
695699
final Class<?> clazz = accessor.getObjectClass();
696700
assertThat(clazz, equalTo(String.class));
697701
}
702+
703+
@Test
704+
public void testViewVarcharVector() throws Exception {
705+
try (VarCharVector varCharVector =
706+
new VarCharVector("", rootAllocatorTestExtension.getRootAllocator());
707+
ViewVarCharVector viewVarCharVector =
708+
new ViewVarCharVector("", rootAllocatorTestExtension.getRootAllocator())) {
709+
varCharVector.allocateNew(1);
710+
viewVarCharVector.allocateNew(1);
711+
712+
ArrowFlightJdbcVarCharVectorAccessor varCharVectorAccessor =
713+
new ArrowFlightJdbcVarCharVectorAccessor(varCharVector, () -> 0, (boolean wasNull) -> {});
714+
ArrowFlightJdbcVarCharVectorAccessor viewVarcharVectorAccessor =
715+
new ArrowFlightJdbcVarCharVectorAccessor(
716+
viewVarCharVector, () -> 0, (boolean wasNull) -> {});
717+
assertNull(viewVarcharVectorAccessor.getString());
718+
719+
varCharVector.set(0, new Text("looooong_string"));
720+
viewVarCharVector.set(0, new Text("looooong_string"));
721+
assertEquals(varCharVectorAccessor.getString(), viewVarcharVectorAccessor.getString());
722+
}
723+
}
698724
}

0 commit comments

Comments
 (0)