org.apache.arrow.flight.sql.FlightSqlProducer Maven / Gradle / Ivy
Show all versions of flight-sql Show documentation
/*
* 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.flight.sql;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static java.util.stream.IntStream.range;
import static org.apache.arrow.flight.sql.impl.FlightSql.ActionBeginSavepointRequest;
import static org.apache.arrow.flight.sql.impl.FlightSql.ActionBeginSavepointResult;
import static org.apache.arrow.flight.sql.impl.FlightSql.ActionBeginTransactionRequest;
import static org.apache.arrow.flight.sql.impl.FlightSql.ActionBeginTransactionResult;
import static org.apache.arrow.flight.sql.impl.FlightSql.ActionCancelQueryRequest;
import static org.apache.arrow.flight.sql.impl.FlightSql.ActionCreatePreparedStatementResult;
import static org.apache.arrow.flight.sql.impl.FlightSql.ActionCreatePreparedSubstraitPlanRequest;
import static org.apache.arrow.flight.sql.impl.FlightSql.ActionEndSavepointRequest;
import static org.apache.arrow.flight.sql.impl.FlightSql.ActionEndTransactionRequest;
import static org.apache.arrow.flight.sql.impl.FlightSql.CommandGetCrossReference;
import static org.apache.arrow.flight.sql.impl.FlightSql.CommandGetDbSchemas;
import static org.apache.arrow.flight.sql.impl.FlightSql.CommandGetExportedKeys;
import static org.apache.arrow.flight.sql.impl.FlightSql.CommandGetImportedKeys;
import static org.apache.arrow.flight.sql.impl.FlightSql.CommandGetXdbcTypeInfo;
import static org.apache.arrow.flight.sql.impl.FlightSql.CommandStatementSubstraitPlan;
import static org.apache.arrow.vector.complex.MapVector.DATA_VECTOR_NAME;
import static org.apache.arrow.vector.complex.MapVector.KEY_NAME;
import static org.apache.arrow.vector.complex.MapVector.VALUE_NAME;
import static org.apache.arrow.vector.types.Types.MinorType.BIGINT;
import static org.apache.arrow.vector.types.Types.MinorType.BIT;
import static org.apache.arrow.vector.types.Types.MinorType.INT;
import static org.apache.arrow.vector.types.Types.MinorType.LIST;
import static org.apache.arrow.vector.types.Types.MinorType.STRUCT;
import static org.apache.arrow.vector.types.Types.MinorType.UINT4;
import static org.apache.arrow.vector.types.Types.MinorType.VARCHAR;
import com.google.common.collect.ImmutableList;
import com.google.protobuf.Any;
import com.google.protobuf.InvalidProtocolBufferException;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.util.List;
import org.apache.arrow.flight.Action;
import org.apache.arrow.flight.ActionType;
import org.apache.arrow.flight.CallStatus;
import org.apache.arrow.flight.CancelFlightInfoRequest;
import org.apache.arrow.flight.CancelStatus;
import org.apache.arrow.flight.CloseSessionRequest;
import org.apache.arrow.flight.CloseSessionResult;
import org.apache.arrow.flight.FlightConstants;
import org.apache.arrow.flight.FlightDescriptor;
import org.apache.arrow.flight.FlightEndpoint;
import org.apache.arrow.flight.FlightInfo;
import org.apache.arrow.flight.FlightProducer;
import org.apache.arrow.flight.FlightStream;
import org.apache.arrow.flight.GetSessionOptionsRequest;
import org.apache.arrow.flight.GetSessionOptionsResult;
import org.apache.arrow.flight.PutResult;
import org.apache.arrow.flight.RenewFlightEndpointRequest;
import org.apache.arrow.flight.Result;
import org.apache.arrow.flight.SchemaResult;
import org.apache.arrow.flight.SetSessionOptionsRequest;
import org.apache.arrow.flight.SetSessionOptionsResult;
import org.apache.arrow.flight.Ticket;
import org.apache.arrow.flight.sql.impl.FlightSql.ActionClosePreparedStatementRequest;
import org.apache.arrow.flight.sql.impl.FlightSql.ActionCreatePreparedStatementRequest;
import org.apache.arrow.flight.sql.impl.FlightSql.CommandGetCatalogs;
import org.apache.arrow.flight.sql.impl.FlightSql.CommandGetPrimaryKeys;
import org.apache.arrow.flight.sql.impl.FlightSql.CommandGetSqlInfo;
import org.apache.arrow.flight.sql.impl.FlightSql.CommandGetTableTypes;
import org.apache.arrow.flight.sql.impl.FlightSql.CommandGetTables;
import org.apache.arrow.flight.sql.impl.FlightSql.CommandPreparedStatementQuery;
import org.apache.arrow.flight.sql.impl.FlightSql.CommandPreparedStatementUpdate;
import org.apache.arrow.flight.sql.impl.FlightSql.CommandStatementIngest;
import org.apache.arrow.flight.sql.impl.FlightSql.CommandStatementQuery;
import org.apache.arrow.flight.sql.impl.FlightSql.CommandStatementUpdate;
import org.apache.arrow.flight.sql.impl.FlightSql.DoPutUpdateResult;
import org.apache.arrow.flight.sql.impl.FlightSql.TicketStatementQuery;
import org.apache.arrow.vector.types.Types.MinorType;
import org.apache.arrow.vector.types.UnionMode;
import org.apache.arrow.vector.types.pojo.ArrowType;
import org.apache.arrow.vector.types.pojo.ArrowType.Union;
import org.apache.arrow.vector.types.pojo.Field;
import org.apache.arrow.vector.types.pojo.FieldType;
import org.apache.arrow.vector.types.pojo.Schema;
/** API to Implement an Arrow Flight SQL producer. */
public interface FlightSqlProducer extends FlightProducer, AutoCloseable {
/**
* Depending on the provided command, method either: 1. Return information about a SQL query, or
* 2. Return information about a prepared statement. In this case, parameters binding is allowed.
*
* @param context Per-call context.
* @param descriptor The descriptor identifying the data stream.
* @return information about the given SQL query, or the given prepared statement.
*/
@Override
default FlightInfo getFlightInfo(CallContext context, FlightDescriptor descriptor) {
final Any command = FlightSqlUtils.parseOrThrow(descriptor.getCommand());
if (command.is(CommandStatementQuery.class)) {
return getFlightInfoStatement(
FlightSqlUtils.unpackOrThrow(command, CommandStatementQuery.class), context, descriptor);
} else if (command.is(CommandStatementSubstraitPlan.class)) {
return getFlightInfoSubstraitPlan(
FlightSqlUtils.unpackOrThrow(command, CommandStatementSubstraitPlan.class),
context,
descriptor);
} else if (command.is(CommandPreparedStatementQuery.class)) {
return getFlightInfoPreparedStatement(
FlightSqlUtils.unpackOrThrow(command, CommandPreparedStatementQuery.class),
context,
descriptor);
} else if (command.is(CommandGetCatalogs.class)) {
return getFlightInfoCatalogs(
FlightSqlUtils.unpackOrThrow(command, CommandGetCatalogs.class), context, descriptor);
} else if (command.is(CommandGetDbSchemas.class)) {
return getFlightInfoSchemas(
FlightSqlUtils.unpackOrThrow(command, CommandGetDbSchemas.class), context, descriptor);
} else if (command.is(CommandGetTables.class)) {
return getFlightInfoTables(
FlightSqlUtils.unpackOrThrow(command, CommandGetTables.class), context, descriptor);
} else if (command.is(CommandGetTableTypes.class)) {
return getFlightInfoTableTypes(
FlightSqlUtils.unpackOrThrow(command, CommandGetTableTypes.class), context, descriptor);
} else if (command.is(CommandGetSqlInfo.class)) {
return getFlightInfoSqlInfo(
FlightSqlUtils.unpackOrThrow(command, CommandGetSqlInfo.class), context, descriptor);
} else if (command.is(CommandGetPrimaryKeys.class)) {
return getFlightInfoPrimaryKeys(
FlightSqlUtils.unpackOrThrow(command, CommandGetPrimaryKeys.class), context, descriptor);
} else if (command.is(CommandGetExportedKeys.class)) {
return getFlightInfoExportedKeys(
FlightSqlUtils.unpackOrThrow(command, CommandGetExportedKeys.class), context, descriptor);
} else if (command.is(CommandGetImportedKeys.class)) {
return getFlightInfoImportedKeys(
FlightSqlUtils.unpackOrThrow(command, CommandGetImportedKeys.class), context, descriptor);
} else if (command.is(CommandGetCrossReference.class)) {
return getFlightInfoCrossReference(
FlightSqlUtils.unpackOrThrow(command, CommandGetCrossReference.class),
context,
descriptor);
} else if (command.is(CommandGetXdbcTypeInfo.class)) {
return getFlightInfoTypeInfo(
FlightSqlUtils.unpackOrThrow(command, CommandGetXdbcTypeInfo.class), context, descriptor);
}
throw CallStatus.INVALID_ARGUMENT
.withDescription("Unrecognized request: " + command.getTypeUrl())
.toRuntimeException();
}
/**
* Returns the schema of the result produced by the SQL query.
*
* @param context Per-call context.
* @param descriptor The descriptor identifying the data stream.
* @return the result set schema.
*/
@Override
default SchemaResult getSchema(CallContext context, FlightDescriptor descriptor) {
final Any command = FlightSqlUtils.parseOrThrow(descriptor.getCommand());
if (command.is(CommandStatementQuery.class)) {
return getSchemaStatement(
FlightSqlUtils.unpackOrThrow(command, CommandStatementQuery.class), context, descriptor);
} else if (command.is(CommandPreparedStatementQuery.class)) {
return getSchemaPreparedStatement(
FlightSqlUtils.unpackOrThrow(command, CommandPreparedStatementQuery.class),
context,
descriptor);
} else if (command.is(CommandStatementSubstraitPlan.class)) {
return getSchemaSubstraitPlan(
FlightSqlUtils.unpackOrThrow(command, CommandStatementSubstraitPlan.class),
context,
descriptor);
} else if (command.is(CommandGetCatalogs.class)) {
return new SchemaResult(Schemas.GET_CATALOGS_SCHEMA);
} else if (command.is(CommandGetCrossReference.class)) {
return new SchemaResult(Schemas.GET_CROSS_REFERENCE_SCHEMA);
} else if (command.is(CommandGetDbSchemas.class)) {
return new SchemaResult(Schemas.GET_SCHEMAS_SCHEMA);
} else if (command.is(CommandGetExportedKeys.class)) {
return new SchemaResult(Schemas.GET_EXPORTED_KEYS_SCHEMA);
} else if (command.is(CommandGetImportedKeys.class)) {
return new SchemaResult(Schemas.GET_IMPORTED_KEYS_SCHEMA);
} else if (command.is(CommandGetPrimaryKeys.class)) {
return new SchemaResult(Schemas.GET_PRIMARY_KEYS_SCHEMA);
} else if (command.is(CommandGetTables.class)) {
if (FlightSqlUtils.unpackOrThrow(command, CommandGetTables.class).getIncludeSchema()) {
return new SchemaResult(Schemas.GET_TABLES_SCHEMA);
}
return new SchemaResult(Schemas.GET_TABLES_SCHEMA_NO_SCHEMA);
} else if (command.is(CommandGetTableTypes.class)) {
return new SchemaResult(Schemas.GET_TABLE_TYPES_SCHEMA);
} else if (command.is(CommandGetSqlInfo.class)) {
return new SchemaResult(Schemas.GET_SQL_INFO_SCHEMA);
} else if (command.is(CommandGetXdbcTypeInfo.class)) {
return new SchemaResult(Schemas.GET_TYPE_INFO_SCHEMA);
}
throw CallStatus.INVALID_ARGUMENT
.withDescription("Unrecognized request: " + command.getTypeUrl())
.toRuntimeException();
}
/**
* Depending on the provided command, method either: 1. Return data for a stream produced by
* executing the provided SQL query, or 2. Return data for a prepared statement. In this case,
* parameters binding is allowed.
*
* @param context Per-call context.
* @param ticket The application-defined ticket identifying this stream.
* @param listener An interface for sending data back to the client.
*/
@Override
default void getStream(CallContext context, Ticket ticket, ServerStreamListener listener) {
final Any command;
try {
command = Any.parseFrom(ticket.getBytes());
} catch (InvalidProtocolBufferException e) {
listener.error(e);
return;
}
if (command.is(TicketStatementQuery.class)) {
getStreamStatement(
FlightSqlUtils.unpackOrThrow(command, TicketStatementQuery.class), context, listener);
} else if (command.is(CommandPreparedStatementQuery.class)) {
getStreamPreparedStatement(
FlightSqlUtils.unpackOrThrow(command, CommandPreparedStatementQuery.class),
context,
listener);
} else if (command.is(CommandGetCatalogs.class)) {
getStreamCatalogs(context, listener);
} else if (command.is(CommandGetDbSchemas.class)) {
getStreamSchemas(
FlightSqlUtils.unpackOrThrow(command, CommandGetDbSchemas.class), context, listener);
} else if (command.is(CommandGetTables.class)) {
getStreamTables(
FlightSqlUtils.unpackOrThrow(command, CommandGetTables.class), context, listener);
} else if (command.is(CommandGetTableTypes.class)) {
getStreamTableTypes(context, listener);
} else if (command.is(CommandGetSqlInfo.class)) {
getStreamSqlInfo(
FlightSqlUtils.unpackOrThrow(command, CommandGetSqlInfo.class), context, listener);
} else if (command.is(CommandGetPrimaryKeys.class)) {
getStreamPrimaryKeys(
FlightSqlUtils.unpackOrThrow(command, CommandGetPrimaryKeys.class), context, listener);
} else if (command.is(CommandGetExportedKeys.class)) {
getStreamExportedKeys(
FlightSqlUtils.unpackOrThrow(command, CommandGetExportedKeys.class), context, listener);
} else if (command.is(CommandGetImportedKeys.class)) {
getStreamImportedKeys(
FlightSqlUtils.unpackOrThrow(command, CommandGetImportedKeys.class), context, listener);
} else if (command.is(CommandGetCrossReference.class)) {
getStreamCrossReference(
FlightSqlUtils.unpackOrThrow(command, CommandGetCrossReference.class), context, listener);
} else if (command.is(CommandGetXdbcTypeInfo.class)) {
getStreamTypeInfo(
FlightSqlUtils.unpackOrThrow(command, CommandGetXdbcTypeInfo.class), context, listener);
} else {
throw CallStatus.INVALID_ARGUMENT
.withDescription("The defined request is invalid.")
.toRuntimeException();
}
}
/**
* Depending on the provided command, method either: 1. Execute provided SQL query as an update
* statement, or 2. Execute provided update SQL query prepared statement. In this case, parameters
* binding is allowed, or 3. Binds parameters to the provided prepared statement, or 4. Bulk
* ingests data provided through the flightStream.
*
* @param context Per-call context.
* @param flightStream The data stream being uploaded.
* @param ackStream The data stream listener for update result acknowledgement.
* @return a Runnable to process the stream.
*/
@Override
default Runnable acceptPut(
CallContext context, FlightStream flightStream, StreamListener ackStream) {
final Any command = FlightSqlUtils.parseOrThrow(flightStream.getDescriptor().getCommand());
if (command.is(CommandStatementUpdate.class)) {
return acceptPutStatement(
FlightSqlUtils.unpackOrThrow(command, CommandStatementUpdate.class),
context,
flightStream,
ackStream);
} else if (command.is(CommandStatementIngest.class)) {
return acceptPutStatementBulkIngest(
FlightSqlUtils.unpackOrThrow(command, CommandStatementIngest.class),
context,
flightStream,
ackStream);
} else if (command.is(CommandStatementSubstraitPlan.class)) {
return acceptPutSubstraitPlan(
FlightSqlUtils.unpackOrThrow(command, CommandStatementSubstraitPlan.class),
context,
flightStream,
ackStream);
} else if (command.is(CommandPreparedStatementUpdate.class)) {
return acceptPutPreparedStatementUpdate(
FlightSqlUtils.unpackOrThrow(command, CommandPreparedStatementUpdate.class),
context,
flightStream,
ackStream);
} else if (command.is(CommandPreparedStatementQuery.class)) {
return acceptPutPreparedStatementQuery(
FlightSqlUtils.unpackOrThrow(command, CommandPreparedStatementQuery.class),
context,
flightStream,
ackStream);
}
throw CallStatus.INVALID_ARGUMENT
.withDescription("The defined request is invalid.")
.toRuntimeException();
}
/**
* Lists all available Flight SQL actions.
*
* @param context Per-call context.
* @param listener An interface for sending data back to the client.
*/
@Override
default void listActions(CallContext context, StreamListener listener) {
FlightSqlUtils.FLIGHT_SQL_ACTIONS.forEach(listener::onNext);
listener.onCompleted();
}
/**
* Performs the requested Flight SQL action.
*
* @param context Per-call context.
* @param action Client-supplied parameters.
* @param listener A stream of responses.
*/
@Override
default void doAction(CallContext context, Action action, StreamListener listener) {
final String actionType = action.getType();
if (actionType.equals(FlightSqlUtils.FLIGHT_SQL_BEGIN_SAVEPOINT.getType())) {
final ActionBeginSavepointRequest request =
FlightSqlUtils.unpackAndParseOrThrow(action.getBody(), ActionBeginSavepointRequest.class);
beginSavepoint(request, context, new ProtoListener<>(listener));
} else if (actionType.equals(FlightSqlUtils.FLIGHT_SQL_BEGIN_TRANSACTION.getType())) {
final ActionBeginTransactionRequest request =
FlightSqlUtils.unpackAndParseOrThrow(
action.getBody(), ActionBeginTransactionRequest.class);
beginTransaction(request, context, new ProtoListener<>(listener));
} else if (actionType.equals(FlightSqlUtils.FLIGHT_SQL_CANCEL_QUERY.getType())) {
//noinspection deprecation
final ActionCancelQueryRequest request =
FlightSqlUtils.unpackAndParseOrThrow(action.getBody(), ActionCancelQueryRequest.class);
final FlightInfo info;
try {
info = FlightInfo.deserialize(request.getInfo().asReadOnlyByteBuffer());
} catch (IOException | URISyntaxException e) {
listener.onError(
CallStatus.INTERNAL
.withDescription("Could not unpack FlightInfo: " + e)
.withCause(e)
.toRuntimeException());
return;
}
cancelQuery(info, context, new CancelListener(listener));
} else if (actionType.equals(FlightSqlUtils.FLIGHT_SQL_CREATE_PREPARED_STATEMENT.getType())) {
final ActionCreatePreparedStatementRequest request =
FlightSqlUtils.unpackAndParseOrThrow(
action.getBody(), ActionCreatePreparedStatementRequest.class);
createPreparedStatement(request, context, listener);
} else if (actionType.equals(
FlightSqlUtils.FLIGHT_SQL_CREATE_PREPARED_SUBSTRAIT_PLAN.getType())) {
final ActionCreatePreparedSubstraitPlanRequest request =
FlightSqlUtils.unpackAndParseOrThrow(
action.getBody(), ActionCreatePreparedSubstraitPlanRequest.class);
createPreparedSubstraitPlan(request, context, new ProtoListener<>(listener));
} else if (actionType.equals(FlightSqlUtils.FLIGHT_SQL_CLOSE_PREPARED_STATEMENT.getType())) {
final ActionClosePreparedStatementRequest request =
FlightSqlUtils.unpackAndParseOrThrow(
action.getBody(), ActionClosePreparedStatementRequest.class);
closePreparedStatement(request, context, new NoResultListener(listener));
} else if (actionType.equals(FlightSqlUtils.FLIGHT_SQL_END_SAVEPOINT.getType())) {
ActionEndSavepointRequest request =
FlightSqlUtils.unpackAndParseOrThrow(action.getBody(), ActionEndSavepointRequest.class);
endSavepoint(request, context, new NoResultListener(listener));
} else if (actionType.equals(FlightSqlUtils.FLIGHT_SQL_END_TRANSACTION.getType())) {
ActionEndTransactionRequest request =
FlightSqlUtils.unpackAndParseOrThrow(action.getBody(), ActionEndTransactionRequest.class);
endTransaction(request, context, new NoResultListener(listener));
} else if (actionType.equals(FlightConstants.CANCEL_FLIGHT_INFO.getType())) {
final CancelFlightInfoRequest request;
try {
request = CancelFlightInfoRequest.deserialize(ByteBuffer.wrap(action.getBody()));
} catch (IOException | URISyntaxException e) {
listener.onError(
CallStatus.INTERNAL
.withDescription("Could not unpack FlightInfo: " + e)
.withCause(e)
.toRuntimeException());
return;
}
cancelFlightInfo(request, context, new CancelStatusListener(listener));
} else if (actionType.equals(FlightConstants.RENEW_FLIGHT_ENDPOINT.getType())) {
final RenewFlightEndpointRequest request;
try {
request = RenewFlightEndpointRequest.deserialize(ByteBuffer.wrap(action.getBody()));
} catch (IOException | URISyntaxException e) {
listener.onError(
CallStatus.INTERNAL
.withDescription("Could not unpack FlightInfo: " + e)
.withCause(e)
.toRuntimeException());
return;
}
renewFlightEndpoint(request, context, new FlightEndpointListener(listener));
} else if (actionType.equals(FlightConstants.SET_SESSION_OPTIONS.getType())) {
final SetSessionOptionsRequest request;
try {
request = SetSessionOptionsRequest.deserialize(ByteBuffer.wrap(action.getBody()));
} catch (IOException e) {
listener.onError(
CallStatus.INTERNAL
.withDescription("Could not unpack SetSessionOptionsRequest: " + e)
.withCause(e)
.toRuntimeException());
return;
}
setSessionOptions(request, context, new SetSessionOptionsResultListener(listener));
} else if (actionType.equals(FlightConstants.GET_SESSION_OPTIONS.getType())) {
final GetSessionOptionsRequest request;
try {
request = GetSessionOptionsRequest.deserialize(ByteBuffer.wrap(action.getBody()));
} catch (IOException e) {
listener.onError(
CallStatus.INTERNAL
.withDescription("Could not unpack GetSessionOptionsRequest: " + e)
.withCause(e)
.toRuntimeException());
return;
}
getSessionOptions(request, context, new GetSessionOptionsResultListener(listener));
} else if (actionType.equals(FlightConstants.CLOSE_SESSION.getType())) {
final CloseSessionRequest request;
try {
request = CloseSessionRequest.deserialize(ByteBuffer.wrap(action.getBody()));
} catch (IOException e) {
listener.onError(
CallStatus.INTERNAL
.withDescription("Could not unpack CloseSessionRequest: " + e)
.withCause(e)
.toRuntimeException());
return;
}
closeSession(request, context, new CloseSessionResultListener(listener));
} else {
throw CallStatus.INVALID_ARGUMENT
.withDescription("Unrecognized request: " + action.getType())
.toRuntimeException();
}
}
/**
* Create a savepoint within a transaction.
*
* @param request The savepoint request.
* @param context Per-call context.
* @param listener The newly created savepoint ID.
*/
default void beginSavepoint(
ActionBeginSavepointRequest request,
CallContext context,
StreamListener listener) {
listener.onError(CallStatus.UNIMPLEMENTED.toRuntimeException());
}
/**
* Begin a transaction.
*
* @param request The transaction request.
* @param context Per-call context.
* @param listener The newly created transaction ID.
*/
default void beginTransaction(
ActionBeginTransactionRequest request,
CallContext context,
StreamListener listener) {
listener.onError(CallStatus.UNIMPLEMENTED.toRuntimeException());
}
/**
* Explicitly cancel a query.
*
* @param request The CancelFlightInfoRequest for the query to cancel.
* @param context Per-call context.
* @param listener An interface for sending data back to the client.
*/
default void cancelFlightInfo(
CancelFlightInfoRequest request, CallContext context, StreamListener listener) {
listener.onError(CallStatus.UNIMPLEMENTED.toRuntimeException());
}
/**
* Explicitly cancel a query.
*
* @param info The FlightInfo of the query to cancel.
* @param context Per-call context.
* @param listener Whether cancellation succeeded.
* @deprecated Prefer {@link #cancelFlightInfo(CancelFlightInfoRequest, CallContext,
* StreamListener)}.
*/
@Deprecated
default void cancelQuery(
FlightInfo info, CallContext context, StreamListener listener) {
CancelFlightInfoRequest request = new CancelFlightInfoRequest(info);
cancelFlightInfo(
request,
context,
new StreamListener() {
@Override
public void onNext(CancelStatus val) {
switch (val) {
case UNSPECIFIED:
listener.onNext(CancelResult.UNSPECIFIED);
break;
case CANCELLED:
listener.onNext(CancelResult.CANCELLED);
break;
case CANCELLING:
listener.onNext(CancelResult.CANCELLING);
break;
case NOT_CANCELLABLE:
listener.onNext(CancelResult.NOT_CANCELLABLE);
break;
default:
// XXX: CheckStyle requires a default clause which arguably makes the code worse.
throw new AssertionError("Unknown enum variant " + val);
}
}
@Override
public void onError(Throwable t) {
listener.onError(t);
}
@Override
public void onCompleted() {
listener.onCompleted();
}
});
}
/**
* Set server session options(s).
*
* @param request The session options to set. For *DBC driver compatibility, servers should
* support converting values from strings.
* @param context Per-call context.
* @param listener An interface for sending data back to the client.
*/
default void setSessionOptions(
SetSessionOptionsRequest request,
CallContext context,
StreamListener listener) {
listener.onError(CallStatus.UNIMPLEMENTED.toRuntimeException());
}
/**
* Get server session option(s).
*
* @param request The (empty) GetSessionOptionsRequest.
* @param context Per-call context.
* @param listener An interface for sending data back to the client.
*/
default void getSessionOptions(
GetSessionOptionsRequest request,
CallContext context,
StreamListener listener) {
listener.onError(CallStatus.UNIMPLEMENTED.toRuntimeException());
}
/**
* Close/invalidate the session.
*
* @param request The (empty) CloseSessionRequest.
* @param context Per-call context.
* @param listener An interface for sending data back to the client.
*/
default void closeSession(
CloseSessionRequest request,
CallContext context,
StreamListener listener) {
listener.onError(CallStatus.UNIMPLEMENTED.toRuntimeException());
}
/**
* Creates a prepared statement on the server and returns a handle and metadata for in a {@link
* ActionCreatePreparedStatementResult} object in a {@link Result} object.
*
* @param request The sql command to generate the prepared statement.
* @param context Per-call context.
* @param listener A stream of responses.
*/
void createPreparedStatement(
ActionCreatePreparedStatementRequest request,
CallContext context,
StreamListener listener);
/**
* Pre-compile a Substrait plan.
*
* @param request The plan.
* @param context Per-call context.
* @param listener The resulting prepared statement.
*/
default void createPreparedSubstraitPlan(
ActionCreatePreparedSubstraitPlanRequest request,
CallContext context,
StreamListener listener) {
listener.onError(CallStatus.UNIMPLEMENTED.toRuntimeException());
}
/**
* Closes a prepared statement on the server. No result is expected.
*
* @param request The sql command to generate the prepared statement.
* @param context Per-call context.
* @param listener A stream of responses.
*/
void closePreparedStatement(
ActionClosePreparedStatementRequest request,
CallContext context,
StreamListener listener);
/**
* Release or roll back to a savepoint.
*
* @param request The savepoint, and whether to release/rollback.
* @param context Per-call context.
* @param listener Call {@link StreamListener#onCompleted()} or {@link
* StreamListener#onError(Throwable)} when done; do not send a result.
*/
default void endSavepoint(
ActionEndSavepointRequest request, CallContext context, StreamListener listener) {
listener.onError(CallStatus.UNIMPLEMENTED.toRuntimeException());
}
/**
* Commit or roll back to a transaction.
*
* @param request The transaction, and whether to release/rollback.
* @param context Per-call context.
* @param listener Call {@link StreamListener#onCompleted()} or {@link
* StreamListener#onError(Throwable)} when done; do not send a result.
*/
default void endTransaction(
ActionEndTransactionRequest request, CallContext context, StreamListener listener) {
listener.onError(CallStatus.UNIMPLEMENTED.toRuntimeException());
}
/**
* Evaluate a SQL query.
*
* @param command The SQL query.
* @param context Per-call context.
* @param descriptor The descriptor identifying the data stream.
* @return Metadata about the stream.
*/
FlightInfo getFlightInfoStatement(
CommandStatementQuery command, CallContext context, FlightDescriptor descriptor);
/**
* Evaluate a Substrait plan.
*
* @param command The Substrait plan.
* @param context Per-call context.
* @param descriptor The descriptor identifying the data stream.
* @return Metadata about the stream.
*/
default FlightInfo getFlightInfoSubstraitPlan(
CommandStatementSubstraitPlan command, CallContext context, FlightDescriptor descriptor) {
throw CallStatus.UNIMPLEMENTED.toRuntimeException();
}
/**
* Gets information about a particular prepared statement data stream.
*
* @param command The prepared statement to generate the data stream.
* @param context Per-call context.
* @param descriptor The descriptor identifying the data stream.
* @return Metadata about the stream.
*/
FlightInfo getFlightInfoPreparedStatement(
CommandPreparedStatementQuery command, CallContext context, FlightDescriptor descriptor);
/**
* Get the result schema for a SQL query.
*
* @param command The SQL query.
* @param context Per-call context.
* @param descriptor The descriptor identifying the data stream.
* @return the schema of the result set.
*/
SchemaResult getSchemaStatement(
CommandStatementQuery command, CallContext context, FlightDescriptor descriptor);
/**
* Get the schema of the result set of a prepared statement.
*
* @param command The prepared statement handle.
* @param context Per-call context.
* @param descriptor The descriptor identifying the data stream.
* @return the schema of the result set.
*/
default SchemaResult getSchemaPreparedStatement(
CommandPreparedStatementQuery command, CallContext context, FlightDescriptor descriptor) {
throw CallStatus.UNIMPLEMENTED
.withDescription("GetSchema with CommandPreparedStatementQuery is not implemented")
.toRuntimeException();
}
/**
* Get the result schema for a Substrait plan.
*
* @param command The Substrait plan.
* @param context Per-call context.
* @param descriptor The descriptor identifying the data stream.
* @return Schema for the stream.
*/
default SchemaResult getSchemaSubstraitPlan(
CommandStatementSubstraitPlan command, CallContext context, FlightDescriptor descriptor) {
throw CallStatus.UNIMPLEMENTED.toRuntimeException();
}
/**
* Returns data for a SQL query based data stream.
*
* @param ticket Ticket message containing the statement handle.
* @param context Per-call context.
* @param listener An interface for sending data back to the client.
*/
void getStreamStatement(
TicketStatementQuery ticket, CallContext context, ServerStreamListener listener);
/**
* Returns data for a particular prepared statement query instance.
*
* @param command The prepared statement to generate the data stream.
* @param context Per-call context.
* @param listener An interface for sending data back to the client.
*/
void getStreamPreparedStatement(
CommandPreparedStatementQuery command, CallContext context, ServerStreamListener listener);
/**
* Accepts uploaded data for a particular SQL query based data stream.
*
* `PutResult`s must be in the form of a {@link DoPutUpdateResult}.
*
* @param command The sql command to generate the data stream.
* @param context Per-call context.
* @param flightStream The data stream being uploaded.
* @param ackStream The result data stream.
* @return A runnable to process the stream.
*/
Runnable acceptPutStatement(
CommandStatementUpdate command,
CallContext context,
FlightStream flightStream,
StreamListener ackStream);
/**
* Accepts uploaded data for a particular bulk ingest data stream.
*
* `PutResult`s must be in the form of a {@link DoPutUpdateResult}.
*
* @param command The bulk ingestion request.
* @param context Per-call context.
* @param flightStream The data stream being uploaded.
* @param ackStream The result data stream.
* @return A runnable to process the stream.
*/
default Runnable acceptPutStatementBulkIngest(
CommandStatementIngest command,
CallContext context,
FlightStream flightStream,
StreamListener ackStream) {
return () -> {
ackStream.onError(CallStatus.UNIMPLEMENTED.toRuntimeException());
};
}
/**
* Handle a Substrait plan with uploaded data.
*
* @param command The Substrait plan to evaluate.
* @param context Per-call context.
* @param flightStream The data stream being uploaded.
* @param ackStream The result data stream.
* @return A runnable to process the stream.
*/
default Runnable acceptPutSubstraitPlan(
CommandStatementSubstraitPlan command,
CallContext context,
FlightStream flightStream,
StreamListener ackStream) {
return () -> {
ackStream.onError(CallStatus.UNIMPLEMENTED.toRuntimeException());
};
}
/**
* Accepts uploaded data for a particular prepared statement data stream.
*
* `PutResult`s must be in the form of a {@link DoPutUpdateResult}.
*
* @param command The prepared statement to generate the data stream.
* @param context Per-call context.
* @param flightStream The data stream being uploaded.
* @param ackStream The result data stream.
* @return A runnable to process the stream.
*/
Runnable acceptPutPreparedStatementUpdate(
CommandPreparedStatementUpdate command,
CallContext context,
FlightStream flightStream,
StreamListener ackStream);
/**
* Accepts uploaded parameter values for a particular prepared statement query.
*
* @param command The prepared statement the parameter values will bind to.
* @param context Per-call context.
* @param flightStream The data stream being uploaded.
* @param ackStream The result data stream.
* @return A runnable to process the stream.
*/
Runnable acceptPutPreparedStatementQuery(
CommandPreparedStatementQuery command,
CallContext context,
FlightStream flightStream,
StreamListener ackStream);
/**
* Returns the SQL Info of the server by returning a {@link CommandGetSqlInfo} in a {@link
* Result}.
*
* @param request request filter parameters.
* @param context Per-call context.
* @param descriptor The descriptor identifying the data stream.
* @return Metadata about the stream.
*/
FlightInfo getFlightInfoSqlInfo(
CommandGetSqlInfo request, CallContext context, FlightDescriptor descriptor);
/**
* Returns data for SQL info based data stream.
*
* @param command The command to generate the data stream.
* @param context Per-call context.
* @param listener An interface for sending data back to the client.
*/
void getStreamSqlInfo(
CommandGetSqlInfo command, CallContext context, ServerStreamListener listener);
/**
* Returns a description of all the data types supported by source.
*
* @param request request filter parameters.
* @param descriptor The descriptor identifying the data stream.
* @return Metadata about the stream.
*/
FlightInfo getFlightInfoTypeInfo(
CommandGetXdbcTypeInfo request, CallContext context, FlightDescriptor descriptor);
/**
* Returns data for type info based data stream.
*
* @param context Per-call context.
* @param listener An interface for sending data back to the client.
*/
void getStreamTypeInfo(
CommandGetXdbcTypeInfo request, CallContext context, ServerStreamListener listener);
/**
* Returns the available catalogs by returning a stream of {@link CommandGetCatalogs} objects in
* {@link Result} objects.
*
* @param request request filter parameters.
* @param context Per-call context.
* @param descriptor The descriptor identifying the data stream.
* @return Metadata about the stream.
*/
FlightInfo getFlightInfoCatalogs(
CommandGetCatalogs request, CallContext context, FlightDescriptor descriptor);
/**
* Returns data for catalogs based data stream.
*
* @param context Per-call context.
* @param listener An interface for sending data back to the client.
*/
void getStreamCatalogs(CallContext context, ServerStreamListener listener);
/**
* Returns the available schemas by returning a stream of {@link CommandGetDbSchemas} objects in
* {@link Result} objects.
*
* @param request request filter parameters.
* @param context Per-call context.
* @param descriptor The descriptor identifying the data stream.
* @return Metadata about the stream.
*/
FlightInfo getFlightInfoSchemas(
CommandGetDbSchemas request, CallContext context, FlightDescriptor descriptor);
/**
* Returns data for schemas based data stream.
*
* @param command The command to generate the data stream.
* @param context Per-call context.
* @param listener An interface for sending data back to the client.
*/
void getStreamSchemas(
CommandGetDbSchemas command, CallContext context, ServerStreamListener listener);
/**
* Returns the available tables by returning a stream of {@link CommandGetTables} objects in
* {@link Result} objects.
*
* @param request request filter parameters.
* @param context Per-call context.
* @param descriptor The descriptor identifying the data stream.
* @return Metadata about the stream.
*/
FlightInfo getFlightInfoTables(
CommandGetTables request, CallContext context, FlightDescriptor descriptor);
/**
* Returns data for tables based data stream.
*
* @param command The command to generate the data stream.
* @param context Per-call context.
* @param listener An interface for sending data back to the client.
*/
void getStreamTables(
CommandGetTables command, CallContext context, ServerStreamListener listener);
/**
* Returns the available table types by returning a stream of {@link CommandGetTableTypes} objects
* in {@link Result} objects.
*
* @param context Per-call context.
* @param descriptor The descriptor identifying the data stream.
* @return Metadata about the stream.
*/
FlightInfo getFlightInfoTableTypes(
CommandGetTableTypes request, CallContext context, FlightDescriptor descriptor);
/**
* Returns data for table types based data stream.
*
* @param context Per-call context.
* @param listener An interface for sending data back to the client.
*/
void getStreamTableTypes(CallContext context, ServerStreamListener listener);
/**
* Returns the available primary keys by returning a stream of {@link CommandGetPrimaryKeys}
* objects in {@link Result} objects.
*
* @param request request filter parameters.
* @param context Per-call context.
* @param descriptor The descriptor identifying the data stream.
* @return Metadata about the stream.
*/
FlightInfo getFlightInfoPrimaryKeys(
CommandGetPrimaryKeys request, CallContext context, FlightDescriptor descriptor);
/**
* Returns data for primary keys based data stream.
*
* @param command The command to generate the data stream.
* @param context Per-call context.
* @param listener An interface for sending data back to the client.
*/
void getStreamPrimaryKeys(
CommandGetPrimaryKeys command, CallContext context, ServerStreamListener listener);
/**
* Retrieves a description of the foreign key columns that reference the given table's primary key
* columns {@link CommandGetExportedKeys} objects in {@link Result} objects.
*
* @param request request filter parameters.
* @param context Per-call context.
* @param descriptor The descriptor identifying the data stream.
* @return Metadata about the stream.
*/
FlightInfo getFlightInfoExportedKeys(
CommandGetExportedKeys request, CallContext context, FlightDescriptor descriptor);
/**
* Retrieves a description of the primary key columns that are referenced by given table's foreign
* key columns {@link CommandGetImportedKeys} objects in {@link Result} objects.
*
* @param request request filter parameters.
* @param context Per-call context.
* @param descriptor The descriptor identifying the data stream.
* @return Metadata about the stream.
*/
FlightInfo getFlightInfoImportedKeys(
CommandGetImportedKeys request, CallContext context, FlightDescriptor descriptor);
/**
* Retrieve a description of the foreign key columns that reference the given table's primary key
* columns {@link CommandGetCrossReference} objects in {@link Result} objects.
*
* @param request request filter parameters.
* @param context Per-call context.
* @param descriptor The descriptor identifying the data stream.
* @return Metadata about the stream.
*/
FlightInfo getFlightInfoCrossReference(
CommandGetCrossReference request, CallContext context, FlightDescriptor descriptor);
/**
* Returns data for foreign keys based data stream.
*
* @param command The command to generate the data stream.
* @param context Per-call context.
* @param listener An interface for sending data back to the client.
*/
void getStreamExportedKeys(
CommandGetExportedKeys command, CallContext context, ServerStreamListener listener);
/**
* Returns data for foreign keys based data stream.
*
* @param command The command to generate the data stream.
* @param context Per-call context.
* @param listener An interface for sending data back to the client.
*/
void getStreamImportedKeys(
CommandGetImportedKeys command, CallContext context, ServerStreamListener listener);
/**
* Returns data for cross reference based data stream.
*
* @param command The command to generate the data stream.
* @param context Per-call context.
* @param listener An interface for sending data back to the client.
*/
void getStreamCrossReference(
CommandGetCrossReference command, CallContext context, ServerStreamListener listener);
/**
* Renew the duration of the given endpoint.
*
* @param request The endpoint to renew.
* @param context Per-call context.
* @param listener An interface for sending data back to the client.
*/
default void renewFlightEndpoint(
RenewFlightEndpointRequest request,
CallContext context,
StreamListener listener) {
listener.onError(CallStatus.UNIMPLEMENTED.toRuntimeException());
}
/** Default schema templates for the {@link FlightSqlProducer}. */
final class Schemas {
public static final Schema GET_TABLES_SCHEMA =
new Schema(
asList(
Field.nullable("catalog_name", VARCHAR.getType()),
Field.nullable("db_schema_name", VARCHAR.getType()),
Field.notNullable("table_name", VARCHAR.getType()),
Field.notNullable("table_type", VARCHAR.getType()),
Field.notNullable("table_schema", MinorType.VARBINARY.getType())));
public static final Schema GET_TABLES_SCHEMA_NO_SCHEMA =
new Schema(
asList(
Field.nullable("catalog_name", VARCHAR.getType()),
Field.nullable("db_schema_name", VARCHAR.getType()),
Field.notNullable("table_name", VARCHAR.getType()),
Field.notNullable("table_type", VARCHAR.getType())));
public static final Schema GET_CATALOGS_SCHEMA =
new Schema(singletonList(Field.notNullable("catalog_name", VARCHAR.getType())));
public static final Schema GET_TABLE_TYPES_SCHEMA =
new Schema(singletonList(Field.notNullable("table_type", VARCHAR.getType())));
public static final Schema GET_SCHEMAS_SCHEMA =
new Schema(
asList(
Field.nullable("catalog_name", VARCHAR.getType()),
Field.notNullable("db_schema_name", VARCHAR.getType())));
private static final Schema GET_IMPORTED_EXPORTED_AND_CROSS_REFERENCE_KEYS_SCHEMA =
new Schema(
asList(
Field.nullable("pk_catalog_name", VARCHAR.getType()),
Field.nullable("pk_db_schema_name", VARCHAR.getType()),
Field.notNullable("pk_table_name", VARCHAR.getType()),
Field.notNullable("pk_column_name", VARCHAR.getType()),
Field.nullable("fk_catalog_name", VARCHAR.getType()),
Field.nullable("fk_db_schema_name", VARCHAR.getType()),
Field.notNullable("fk_table_name", VARCHAR.getType()),
Field.notNullable("fk_column_name", VARCHAR.getType()),
Field.notNullable("key_sequence", INT.getType()),
Field.nullable("fk_key_name", VARCHAR.getType()),
Field.nullable("pk_key_name", VARCHAR.getType()),
Field.notNullable("update_rule", MinorType.UINT1.getType()),
Field.notNullable("delete_rule", MinorType.UINT1.getType())));
public static final Schema GET_IMPORTED_KEYS_SCHEMA =
GET_IMPORTED_EXPORTED_AND_CROSS_REFERENCE_KEYS_SCHEMA;
public static final Schema GET_EXPORTED_KEYS_SCHEMA =
GET_IMPORTED_EXPORTED_AND_CROSS_REFERENCE_KEYS_SCHEMA;
public static final Schema GET_CROSS_REFERENCE_SCHEMA =
GET_IMPORTED_EXPORTED_AND_CROSS_REFERENCE_KEYS_SCHEMA;
private static final List GET_SQL_INFO_DENSE_UNION_SCHEMA_FIELDS =
asList(
Field.notNullable("string_value", VARCHAR.getType()),
Field.notNullable("bool_value", BIT.getType()),
Field.notNullable("bigint_value", BIGINT.getType()),
Field.notNullable("int32_bitmask", INT.getType()),
new Field(
"string_list",
FieldType.notNullable(LIST.getType()),
singletonList(Field.nullable("item", VARCHAR.getType()))),
new Field(
"int32_to_int32_list_map",
FieldType.notNullable(new ArrowType.Map(false)),
singletonList(
new Field(
DATA_VECTOR_NAME,
new FieldType(false, STRUCT.getType(), null),
ImmutableList.of(
Field.notNullable(KEY_NAME, INT.getType()),
new Field(
VALUE_NAME,
FieldType.nullable(LIST.getType()),
singletonList(Field.nullable("item", INT.getType()))))))));
public static final Schema GET_SQL_INFO_SCHEMA =
new Schema(
asList(
Field.notNullable("info_name", UINT4.getType()),
new Field(
"value",
FieldType.notNullable(
new Union(
UnionMode.Dense,
range(0, GET_SQL_INFO_DENSE_UNION_SCHEMA_FIELDS.size()).toArray())),
GET_SQL_INFO_DENSE_UNION_SCHEMA_FIELDS)));
public static final Schema GET_TYPE_INFO_SCHEMA =
new Schema(
asList(
Field.notNullable("type_name", VARCHAR.getType()),
Field.notNullable("data_type", INT.getType()),
Field.nullable("column_size", INT.getType()),
Field.nullable("literal_prefix", VARCHAR.getType()),
Field.nullable("literal_suffix", VARCHAR.getType()),
new Field(
"create_params",
FieldType.nullable(LIST.getType()),
singletonList(Field.notNullable("item", VARCHAR.getType()))),
Field.notNullable("nullable", INT.getType()),
Field.notNullable("case_sensitive", BIT.getType()),
Field.notNullable("searchable", INT.getType()),
Field.nullable("unsigned_attribute", BIT.getType()),
Field.notNullable("fixed_prec_scale", BIT.getType()),
Field.nullable("auto_increment", BIT.getType()),
Field.nullable("local_type_name", VARCHAR.getType()),
Field.nullable("minimum_scale", INT.getType()),
Field.nullable("maximum_scale", INT.getType()),
Field.notNullable("sql_data_type", INT.getType()),
Field.nullable("datetime_subcode", INT.getType()),
Field.nullable("num_prec_radix", INT.getType()),
Field.nullable("interval_precision", INT.getType())));
public static final Schema GET_PRIMARY_KEYS_SCHEMA =
new Schema(
asList(
Field.nullable("catalog_name", VARCHAR.getType()),
Field.nullable("db_schema_name", VARCHAR.getType()),
Field.notNullable("table_name", VARCHAR.getType()),
Field.notNullable("column_name", VARCHAR.getType()),
Field.notNullable("key_sequence", INT.getType()),
Field.nullable("key_name", VARCHAR.getType())));
private Schemas() {
// Prevent instantiation.
}
}
}