1use std::fmt::{Display, Formatter};
21use std::pin::Pin;
22
23use super::{
24 ActionBeginSavepointRequest, ActionBeginSavepointResult, ActionBeginTransactionRequest,
25 ActionBeginTransactionResult, ActionCancelQueryRequest, ActionCancelQueryResult,
26 ActionClosePreparedStatementRequest, ActionCreatePreparedStatementRequest,
27 ActionCreatePreparedStatementResult, ActionCreatePreparedSubstraitPlanRequest,
28 ActionEndSavepointRequest, ActionEndTransactionRequest, Any, Command, CommandGetCatalogs,
29 CommandGetCrossReference, CommandGetDbSchemas, CommandGetExportedKeys, CommandGetImportedKeys,
30 CommandGetPrimaryKeys, CommandGetSqlInfo, CommandGetTableTypes, CommandGetTables,
31 CommandGetXdbcTypeInfo, CommandPreparedStatementQuery, CommandPreparedStatementUpdate,
32 CommandStatementIngest, CommandStatementQuery, CommandStatementSubstraitPlan,
33 CommandStatementUpdate, DoPutPreparedStatementResult, DoPutUpdateResult, ProstMessageExt,
34 SqlInfo, TicketStatementQuery,
35};
36use crate::{
37 Action, ActionType, Criteria, Empty, FlightData, FlightDescriptor, FlightInfo,
38 HandshakeRequest, HandshakeResponse, PutResult, SchemaResult, Ticket,
39 flight_service_server::FlightService, r#gen::PollInfo,
40};
41use futures::{Stream, StreamExt, stream::Peekable};
42use prost::Message;
43use tonic::{Request, Response, Status, Streaming};
44
45pub(crate) static CREATE_PREPARED_STATEMENT: &str = "CreatePreparedStatement";
46pub(crate) static CLOSE_PREPARED_STATEMENT: &str = "ClosePreparedStatement";
47pub(crate) static CREATE_PREPARED_SUBSTRAIT_PLAN: &str = "CreatePreparedSubstraitPlan";
48pub(crate) static BEGIN_TRANSACTION: &str = "BeginTransaction";
49pub(crate) static END_TRANSACTION: &str = "EndTransaction";
50pub(crate) static BEGIN_SAVEPOINT: &str = "BeginSavepoint";
51pub(crate) static END_SAVEPOINT: &str = "EndSavepoint";
52pub(crate) static CANCEL_QUERY: &str = "CancelQuery";
53
54#[tonic::async_trait]
56pub trait FlightSqlService: Sync + Send + Sized + 'static {
57 type FlightService: FlightService;
59
60 async fn do_handshake(
63 &self,
64 _request: Request<Streaming<HandshakeRequest>>,
65 ) -> Result<
66 Response<Pin<Box<dyn Stream<Item = Result<HandshakeResponse, Status>> + Send>>>,
67 Status,
68 > {
69 Err(Status::unimplemented(
70 "Handshake has no default implementation",
71 ))
72 }
73
74 async fn do_get_fallback(
76 &self,
77 _request: Request<Ticket>,
78 message: Any,
79 ) -> Result<Response<<Self as FlightService>::DoGetStream>, Status> {
80 Err(Status::unimplemented(format!(
81 "do_get: The defined request is invalid: {}",
82 message.type_url
83 )))
84 }
85
86 async fn get_flight_info_statement(
88 &self,
89 _query: CommandStatementQuery,
90 _request: Request<FlightDescriptor>,
91 ) -> Result<Response<FlightInfo>, Status> {
92 Err(Status::unimplemented(
93 "get_flight_info_statement has no default implementation",
94 ))
95 }
96
97 async fn get_flight_info_substrait_plan(
99 &self,
100 _query: CommandStatementSubstraitPlan,
101 _request: Request<FlightDescriptor>,
102 ) -> Result<Response<FlightInfo>, Status> {
103 Err(Status::unimplemented(
104 "get_flight_info_substrait_plan has no default implementation",
105 ))
106 }
107
108 async fn get_flight_info_prepared_statement(
110 &self,
111 _query: CommandPreparedStatementQuery,
112 _request: Request<FlightDescriptor>,
113 ) -> Result<Response<FlightInfo>, Status> {
114 Err(Status::unimplemented(
115 "get_flight_info_prepared_statement has no default implementation",
116 ))
117 }
118
119 async fn get_flight_info_catalogs(
121 &self,
122 _query: CommandGetCatalogs,
123 _request: Request<FlightDescriptor>,
124 ) -> Result<Response<FlightInfo>, Status> {
125 Err(Status::unimplemented(
126 "get_flight_info_catalogs has no default implementation",
127 ))
128 }
129
130 async fn get_flight_info_schemas(
132 &self,
133 _query: CommandGetDbSchemas,
134 _request: Request<FlightDescriptor>,
135 ) -> Result<Response<FlightInfo>, Status> {
136 Err(Status::unimplemented(
137 "get_flight_info_schemas has no default implementation",
138 ))
139 }
140
141 async fn get_flight_info_tables(
143 &self,
144 _query: CommandGetTables,
145 _request: Request<FlightDescriptor>,
146 ) -> Result<Response<FlightInfo>, Status> {
147 Err(Status::unimplemented(
148 "get_flight_info_tables has no default implementation",
149 ))
150 }
151
152 async fn get_flight_info_table_types(
154 &self,
155 _query: CommandGetTableTypes,
156 _request: Request<FlightDescriptor>,
157 ) -> Result<Response<FlightInfo>, Status> {
158 Err(Status::unimplemented(
159 "get_flight_info_table_types has no default implementation",
160 ))
161 }
162
163 async fn get_flight_info_sql_info(
165 &self,
166 _query: CommandGetSqlInfo,
167 _request: Request<FlightDescriptor>,
168 ) -> Result<Response<FlightInfo>, Status> {
169 Err(Status::unimplemented(
170 "get_flight_info_sql_info has no default implementation",
171 ))
172 }
173
174 async fn get_flight_info_primary_keys(
176 &self,
177 _query: CommandGetPrimaryKeys,
178 _request: Request<FlightDescriptor>,
179 ) -> Result<Response<FlightInfo>, Status> {
180 Err(Status::unimplemented(
181 "get_flight_info_primary_keys has no default implementation",
182 ))
183 }
184
185 async fn get_flight_info_exported_keys(
187 &self,
188 _query: CommandGetExportedKeys,
189 _request: Request<FlightDescriptor>,
190 ) -> Result<Response<FlightInfo>, Status> {
191 Err(Status::unimplemented(
192 "get_flight_info_exported_keys has no default implementation",
193 ))
194 }
195
196 async fn get_flight_info_imported_keys(
198 &self,
199 _query: CommandGetImportedKeys,
200 _request: Request<FlightDescriptor>,
201 ) -> Result<Response<FlightInfo>, Status> {
202 Err(Status::unimplemented(
203 "get_flight_info_imported_keys has no default implementation",
204 ))
205 }
206
207 async fn get_flight_info_cross_reference(
209 &self,
210 _query: CommandGetCrossReference,
211 _request: Request<FlightDescriptor>,
212 ) -> Result<Response<FlightInfo>, Status> {
213 Err(Status::unimplemented(
214 "get_flight_info_cross_reference has no default implementation",
215 ))
216 }
217
218 async fn get_flight_info_xdbc_type_info(
220 &self,
221 _query: CommandGetXdbcTypeInfo,
222 _request: Request<FlightDescriptor>,
223 ) -> Result<Response<FlightInfo>, Status> {
224 Err(Status::unimplemented(
225 "get_flight_info_xdbc_type_info has no default implementation",
226 ))
227 }
228
229 async fn get_flight_info_fallback(
231 &self,
232 cmd: Command,
233 _request: Request<FlightDescriptor>,
234 ) -> Result<Response<FlightInfo>, Status> {
235 Err(Status::unimplemented(format!(
236 "get_flight_info: The defined request is invalid: {}",
237 cmd.type_url()
238 )))
239 }
240
241 async fn do_get_statement(
245 &self,
246 _ticket: TicketStatementQuery,
247 _request: Request<Ticket>,
248 ) -> Result<Response<<Self as FlightService>::DoGetStream>, Status> {
249 Err(Status::unimplemented(
250 "do_get_statement has no default implementation",
251 ))
252 }
253
254 async fn do_get_prepared_statement(
256 &self,
257 _query: CommandPreparedStatementQuery,
258 _request: Request<Ticket>,
259 ) -> Result<Response<<Self as FlightService>::DoGetStream>, Status> {
260 Err(Status::unimplemented(
261 "do_get_prepared_statement has no default implementation",
262 ))
263 }
264
265 async fn do_get_catalogs(
267 &self,
268 _query: CommandGetCatalogs,
269 _request: Request<Ticket>,
270 ) -> Result<Response<<Self as FlightService>::DoGetStream>, Status> {
271 Err(Status::unimplemented(
272 "do_get_catalogs has no default implementation",
273 ))
274 }
275
276 async fn do_get_schemas(
278 &self,
279 _query: CommandGetDbSchemas,
280 _request: Request<Ticket>,
281 ) -> Result<Response<<Self as FlightService>::DoGetStream>, Status> {
282 Err(Status::unimplemented(
283 "do_get_schemas has no default implementation",
284 ))
285 }
286
287 async fn do_get_tables(
289 &self,
290 _query: CommandGetTables,
291 _request: Request<Ticket>,
292 ) -> Result<Response<<Self as FlightService>::DoGetStream>, Status> {
293 Err(Status::unimplemented(
294 "do_get_tables has no default implementation",
295 ))
296 }
297
298 async fn do_get_table_types(
300 &self,
301 _query: CommandGetTableTypes,
302 _request: Request<Ticket>,
303 ) -> Result<Response<<Self as FlightService>::DoGetStream>, Status> {
304 Err(Status::unimplemented(
305 "do_get_table_types has no default implementation",
306 ))
307 }
308
309 async fn do_get_sql_info(
311 &self,
312 _query: CommandGetSqlInfo,
313 _request: Request<Ticket>,
314 ) -> Result<Response<<Self as FlightService>::DoGetStream>, Status> {
315 Err(Status::unimplemented(
316 "do_get_sql_info has no default implementation",
317 ))
318 }
319
320 async fn do_get_primary_keys(
322 &self,
323 _query: CommandGetPrimaryKeys,
324 _request: Request<Ticket>,
325 ) -> Result<Response<<Self as FlightService>::DoGetStream>, Status> {
326 Err(Status::unimplemented(
327 "do_get_primary_keys has no default implementation",
328 ))
329 }
330
331 async fn do_get_exported_keys(
333 &self,
334 _query: CommandGetExportedKeys,
335 _request: Request<Ticket>,
336 ) -> Result<Response<<Self as FlightService>::DoGetStream>, Status> {
337 Err(Status::unimplemented(
338 "do_get_exported_keys has no default implementation",
339 ))
340 }
341
342 async fn do_get_imported_keys(
344 &self,
345 _query: CommandGetImportedKeys,
346 _request: Request<Ticket>,
347 ) -> Result<Response<<Self as FlightService>::DoGetStream>, Status> {
348 Err(Status::unimplemented(
349 "do_get_imported_keys has no default implementation",
350 ))
351 }
352
353 async fn do_get_cross_reference(
355 &self,
356 _query: CommandGetCrossReference,
357 _request: Request<Ticket>,
358 ) -> Result<Response<<Self as FlightService>::DoGetStream>, Status> {
359 Err(Status::unimplemented(
360 "do_get_cross_reference has no default implementation",
361 ))
362 }
363
364 async fn do_get_xdbc_type_info(
366 &self,
367 _query: CommandGetXdbcTypeInfo,
368 _request: Request<Ticket>,
369 ) -> Result<Response<<Self as FlightService>::DoGetStream>, Status> {
370 Err(Status::unimplemented(
371 "do_get_xdbc_type_info has no default implementation",
372 ))
373 }
374
375 async fn do_put_fallback(
379 &self,
380 _request: Request<PeekableFlightDataStream>,
381 message: Any,
382 ) -> Result<Response<<Self as FlightService>::DoPutStream>, Status> {
383 Err(Status::unimplemented(format!(
384 "do_put: The defined request is invalid: {}",
385 message.type_url
386 )))
387 }
388
389 async fn do_put_error_callback(
391 &self,
392 _request: Request<PeekableFlightDataStream>,
393 error: DoPutError,
394 ) -> Result<Response<<Self as FlightService>::DoPutStream>, Status> {
395 Err(Status::unimplemented(format!("Unhandled Error: {error}")))
396 }
397
398 async fn do_put_statement_update(
400 &self,
401 _ticket: CommandStatementUpdate,
402 _request: Request<PeekableFlightDataStream>,
403 ) -> Result<i64, Status> {
404 Err(Status::unimplemented(
405 "do_put_statement_update has no default implementation",
406 ))
407 }
408
409 async fn do_put_statement_ingest(
411 &self,
412 _ticket: CommandStatementIngest,
413 _request: Request<PeekableFlightDataStream>,
414 ) -> Result<i64, Status> {
415 Err(Status::unimplemented(
416 "do_put_statement_ingest has no default implementation",
417 ))
418 }
419
420 async fn do_put_prepared_statement_query(
426 &self,
427 _query: CommandPreparedStatementQuery,
428 _request: Request<PeekableFlightDataStream>,
429 ) -> Result<DoPutPreparedStatementResult, Status> {
430 Err(Status::unimplemented(
431 "do_put_prepared_statement_query has no default implementation",
432 ))
433 }
434
435 async fn do_put_prepared_statement_update(
437 &self,
438 _query: CommandPreparedStatementUpdate,
439 _request: Request<PeekableFlightDataStream>,
440 ) -> Result<i64, Status> {
441 Err(Status::unimplemented(
442 "do_put_prepared_statement_update has no default implementation",
443 ))
444 }
445
446 async fn do_put_substrait_plan(
448 &self,
449 _query: CommandStatementSubstraitPlan,
450 _request: Request<PeekableFlightDataStream>,
451 ) -> Result<i64, Status> {
452 Err(Status::unimplemented(
453 "do_put_substrait_plan has no default implementation",
454 ))
455 }
456
457 async fn do_action_fallback(
461 &self,
462 request: Request<Action>,
463 ) -> Result<Response<<Self as FlightService>::DoActionStream>, Status> {
464 Err(Status::invalid_argument(format!(
465 "do_action: The defined request is invalid: {:?}",
466 request.get_ref().r#type
467 )))
468 }
469
470 async fn list_custom_actions(&self) -> Option<Vec<Result<ActionType, Status>>> {
472 None
473 }
474
475 async fn do_action_create_prepared_statement(
477 &self,
478 _query: ActionCreatePreparedStatementRequest,
479 _request: Request<Action>,
480 ) -> Result<ActionCreatePreparedStatementResult, Status> {
481 Err(Status::unimplemented(
482 "do_action_create_prepared_statement has no default implementation",
483 ))
484 }
485
486 async fn do_action_close_prepared_statement(
488 &self,
489 _query: ActionClosePreparedStatementRequest,
490 _request: Request<Action>,
491 ) -> Result<(), Status> {
492 Err(Status::unimplemented(
493 "do_action_close_prepared_statement has no default implementation",
494 ))
495 }
496
497 async fn do_action_create_prepared_substrait_plan(
499 &self,
500 _query: ActionCreatePreparedSubstraitPlanRequest,
501 _request: Request<Action>,
502 ) -> Result<ActionCreatePreparedStatementResult, Status> {
503 Err(Status::unimplemented(
504 "do_action_create_prepared_substrait_plan has no default implementation",
505 ))
506 }
507
508 async fn do_action_begin_transaction(
510 &self,
511 _query: ActionBeginTransactionRequest,
512 _request: Request<Action>,
513 ) -> Result<ActionBeginTransactionResult, Status> {
514 Err(Status::unimplemented(
515 "do_action_begin_transaction has no default implementation",
516 ))
517 }
518
519 async fn do_action_end_transaction(
521 &self,
522 _query: ActionEndTransactionRequest,
523 _request: Request<Action>,
524 ) -> Result<(), Status> {
525 Err(Status::unimplemented(
526 "do_action_end_transaction has no default implementation",
527 ))
528 }
529
530 async fn do_action_begin_savepoint(
532 &self,
533 _query: ActionBeginSavepointRequest,
534 _request: Request<Action>,
535 ) -> Result<ActionBeginSavepointResult, Status> {
536 Err(Status::unimplemented(
537 "do_action_begin_savepoint has no default implementation",
538 ))
539 }
540
541 async fn do_action_end_savepoint(
543 &self,
544 _query: ActionEndSavepointRequest,
545 _request: Request<Action>,
546 ) -> Result<(), Status> {
547 Err(Status::unimplemented(
548 "do_action_end_savepoint has no default implementation",
549 ))
550 }
551
552 async fn do_action_cancel_query(
554 &self,
555 _query: ActionCancelQueryRequest,
556 _request: Request<Action>,
557 ) -> Result<ActionCancelQueryResult, Status> {
558 Err(Status::unimplemented(
559 "do_action_cancel_query has no default implementation",
560 ))
561 }
562
563 async fn do_exchange_fallback(
566 &self,
567 _request: Request<Streaming<FlightData>>,
568 ) -> Result<Response<<Self as FlightService>::DoExchangeStream>, Status> {
569 Err(Status::unimplemented("Not yet implemented"))
570 }
571
572 #[deprecated(
574 since = "60.1.0",
575 note = "Not used in request handling and doesn't accept a value to register. Use `SqlInfoDataBuilder::append` instead"
576 )]
577 async fn register_sql_info(&self, _id: i32, _result: &SqlInfo) {}
578}
579
580#[tonic::async_trait]
582impl<T: 'static> FlightService for T
583where
584 T: FlightSqlService + Send,
585{
586 type HandshakeStream =
587 Pin<Box<dyn Stream<Item = Result<HandshakeResponse, Status>> + Send + 'static>>;
588 type ListFlightsStream =
589 Pin<Box<dyn Stream<Item = Result<FlightInfo, Status>> + Send + 'static>>;
590 type DoGetStream = Pin<Box<dyn Stream<Item = Result<FlightData, Status>> + Send + 'static>>;
591 type DoPutStream = Pin<Box<dyn Stream<Item = Result<PutResult, Status>> + Send + 'static>>;
592 type DoActionStream =
593 Pin<Box<dyn Stream<Item = Result<super::super::Result, Status>> + Send + 'static>>;
594 type ListActionsStream =
595 Pin<Box<dyn Stream<Item = Result<ActionType, Status>> + Send + 'static>>;
596 type DoExchangeStream =
597 Pin<Box<dyn Stream<Item = Result<FlightData, Status>> + Send + 'static>>;
598
599 async fn handshake(
600 &self,
601 request: Request<Streaming<HandshakeRequest>>,
602 ) -> Result<Response<Self::HandshakeStream>, Status> {
603 let res = self.do_handshake(request).await?;
604 Ok(res)
605 }
606
607 async fn list_flights(
608 &self,
609 _request: Request<Criteria>,
610 ) -> Result<Response<Self::ListFlightsStream>, Status> {
611 Err(Status::unimplemented("Not yet implemented"))
612 }
613
614 async fn get_flight_info(
615 &self,
616 request: Request<FlightDescriptor>,
617 ) -> Result<Response<FlightInfo>, Status> {
618 let message = Any::decode(&*request.get_ref().cmd).map_err(decode_error_to_status)?;
619
620 match Command::try_from(message).map_err(arrow_error_to_status)? {
621 Command::CommandStatementQuery(token) => {
622 self.get_flight_info_statement(token, request).await
623 }
624 Command::CommandPreparedStatementQuery(handle) => {
625 self.get_flight_info_prepared_statement(handle, request)
626 .await
627 }
628 Command::CommandStatementSubstraitPlan(handle) => {
629 self.get_flight_info_substrait_plan(handle, request).await
630 }
631 Command::CommandGetCatalogs(token) => {
632 self.get_flight_info_catalogs(token, request).await
633 }
634 Command::CommandGetDbSchemas(token) => {
635 return self.get_flight_info_schemas(token, request).await;
636 }
637 Command::CommandGetTables(token) => self.get_flight_info_tables(token, request).await,
638 Command::CommandGetTableTypes(token) => {
639 self.get_flight_info_table_types(token, request).await
640 }
641 Command::CommandGetSqlInfo(token) => {
642 self.get_flight_info_sql_info(token, request).await
643 }
644 Command::CommandGetPrimaryKeys(token) => {
645 self.get_flight_info_primary_keys(token, request).await
646 }
647 Command::CommandGetExportedKeys(token) => {
648 self.get_flight_info_exported_keys(token, request).await
649 }
650 Command::CommandGetImportedKeys(token) => {
651 self.get_flight_info_imported_keys(token, request).await
652 }
653 Command::CommandGetCrossReference(token) => {
654 self.get_flight_info_cross_reference(token, request).await
655 }
656 Command::CommandGetXdbcTypeInfo(token) => {
657 self.get_flight_info_xdbc_type_info(token, request).await
658 }
659 cmd => self.get_flight_info_fallback(cmd, request).await,
660 }
661 }
662
663 async fn poll_flight_info(
664 &self,
665 _request: Request<FlightDescriptor>,
666 ) -> Result<Response<PollInfo>, Status> {
667 Err(Status::unimplemented("Not yet implemented"))
668 }
669
670 async fn get_schema(
671 &self,
672 _request: Request<FlightDescriptor>,
673 ) -> Result<Response<SchemaResult>, Status> {
674 Err(Status::unimplemented("Not yet implemented"))
675 }
676
677 async fn do_get(
678 &self,
679 request: Request<Ticket>,
680 ) -> Result<Response<Self::DoGetStream>, Status> {
681 let msg: Any =
682 Message::decode(&*request.get_ref().ticket).map_err(decode_error_to_status)?;
683
684 match Command::try_from(msg).map_err(arrow_error_to_status)? {
685 Command::TicketStatementQuery(command) => self.do_get_statement(command, request).await,
686 Command::CommandPreparedStatementQuery(command) => {
687 self.do_get_prepared_statement(command, request).await
688 }
689 Command::CommandGetCatalogs(command) => self.do_get_catalogs(command, request).await,
690 Command::CommandGetDbSchemas(command) => self.do_get_schemas(command, request).await,
691 Command::CommandGetTables(command) => self.do_get_tables(command, request).await,
692 Command::CommandGetTableTypes(command) => {
693 self.do_get_table_types(command, request).await
694 }
695 Command::CommandGetSqlInfo(command) => self.do_get_sql_info(command, request).await,
696 Command::CommandGetPrimaryKeys(command) => {
697 self.do_get_primary_keys(command, request).await
698 }
699 Command::CommandGetExportedKeys(command) => {
700 self.do_get_exported_keys(command, request).await
701 }
702 Command::CommandGetImportedKeys(command) => {
703 self.do_get_imported_keys(command, request).await
704 }
705 Command::CommandGetCrossReference(command) => {
706 self.do_get_cross_reference(command, request).await
707 }
708 Command::CommandGetXdbcTypeInfo(command) => {
709 self.do_get_xdbc_type_info(command, request).await
710 }
711 cmd => self.do_get_fallback(request, cmd.into_any()).await,
712 }
713 }
714
715 async fn do_put(
716 &self,
717 request: Request<Streaming<FlightData>>,
718 ) -> Result<Response<Self::DoPutStream>, Status> {
719 let mut request = request.map(PeekableFlightDataStream::new);
726 let mut stream = Pin::new(request.get_mut());
727
728 let peeked_item = stream.peek().await.cloned();
729 let Some(cmd) = peeked_item else {
730 return self
731 .do_put_error_callback(request, DoPutError::MissingCommand)
732 .await;
733 };
734
735 let Some(flight_descriptor) = cmd?.flight_descriptor else {
736 return self
737 .do_put_error_callback(request, DoPutError::MissingFlightDescriptor)
738 .await;
739 };
740 let message = Any::decode(flight_descriptor.cmd).map_err(decode_error_to_status)?;
741 match Command::try_from(message).map_err(arrow_error_to_status)? {
742 Command::CommandStatementUpdate(command) => {
743 let record_count = self.do_put_statement_update(command, request).await?;
744 let result = DoPutUpdateResult { record_count };
745 let output = futures::stream::iter(vec![Ok(PutResult {
746 app_metadata: result.encode_to_vec().into(),
747 })]);
748 Ok(Response::new(Box::pin(output)))
749 }
750 Command::CommandStatementIngest(command) => {
751 let record_count = self.do_put_statement_ingest(command, request).await?;
752 let result = DoPutUpdateResult { record_count };
753 let output = futures::stream::iter(vec![Ok(PutResult {
754 app_metadata: result.encode_to_vec().into(),
755 })]);
756 Ok(Response::new(Box::pin(output)))
757 }
758 Command::CommandPreparedStatementQuery(command) => {
759 let result = self
760 .do_put_prepared_statement_query(command, request)
761 .await?;
762 let output = futures::stream::iter(vec![Ok(PutResult {
763 app_metadata: result.encode_to_vec().into(),
764 })]);
765 Ok(Response::new(Box::pin(output)))
766 }
767 Command::CommandStatementSubstraitPlan(command) => {
768 let record_count = self.do_put_substrait_plan(command, request).await?;
769 let result = DoPutUpdateResult { record_count };
770 let output = futures::stream::iter(vec![Ok(PutResult {
771 app_metadata: result.encode_to_vec().into(),
772 })]);
773 Ok(Response::new(Box::pin(output)))
774 }
775 Command::CommandPreparedStatementUpdate(command) => {
776 let record_count = self
777 .do_put_prepared_statement_update(command, request)
778 .await?;
779 let result = DoPutUpdateResult { record_count };
780 let output = futures::stream::iter(vec![Ok(PutResult {
781 app_metadata: result.encode_to_vec().into(),
782 })]);
783 Ok(Response::new(Box::pin(output)))
784 }
785 cmd => self.do_put_fallback(request, cmd.into_any()).await,
786 }
787 }
788
789 async fn list_actions(
790 &self,
791 _request: Request<Empty>,
792 ) -> Result<Response<Self::ListActionsStream>, Status> {
793 let create_prepared_statement_action_type = ActionType {
794 r#type: CREATE_PREPARED_STATEMENT.to_string(),
795 description: "Creates a reusable prepared statement resource on the server.\n
796 Request Message: ActionCreatePreparedStatementRequest\n
797 Response Message: ActionCreatePreparedStatementResult"
798 .into(),
799 };
800 let close_prepared_statement_action_type = ActionType {
801 r#type: CLOSE_PREPARED_STATEMENT.to_string(),
802 description: "Closes a reusable prepared statement resource on the server.\n
803 Request Message: ActionClosePreparedStatementRequest\n
804 Response Message: N/A"
805 .into(),
806 };
807 let create_prepared_substrait_plan_action_type = ActionType {
808 r#type: CREATE_PREPARED_SUBSTRAIT_PLAN.to_string(),
809 description: "Creates a reusable prepared substrait plan resource on the server.\n
810 Request Message: ActionCreatePreparedSubstraitPlanRequest\n
811 Response Message: ActionCreatePreparedStatementResult"
812 .into(),
813 };
814 let begin_transaction_action_type = ActionType {
815 r#type: BEGIN_TRANSACTION.to_string(),
816 description: "Begins a transaction.\n
817 Request Message: ActionBeginTransactionRequest\n
818 Response Message: ActionBeginTransactionResult"
819 .into(),
820 };
821 let end_transaction_action_type = ActionType {
822 r#type: END_TRANSACTION.to_string(),
823 description: "Ends a transaction\n
824 Request Message: ActionEndTransactionRequest\n
825 Response Message: N/A"
826 .into(),
827 };
828 let begin_savepoint_action_type = ActionType {
829 r#type: BEGIN_SAVEPOINT.to_string(),
830 description: "Begins a savepoint.\n
831 Request Message: ActionBeginSavepointRequest\n
832 Response Message: ActionBeginSavepointResult"
833 .into(),
834 };
835 let end_savepoint_action_type = ActionType {
836 r#type: END_SAVEPOINT.to_string(),
837 description: "Ends a savepoint\n
838 Request Message: ActionEndSavepointRequest\n
839 Response Message: N/A"
840 .into(),
841 };
842 let cancel_query_action_type = ActionType {
843 r#type: CANCEL_QUERY.to_string(),
844 description: "Cancels a query\n
845 Request Message: ActionCancelQueryRequest\n
846 Response Message: ActionCancelQueryResult"
847 .into(),
848 };
849 let mut actions: Vec<Result<ActionType, Status>> = vec![
850 Ok(create_prepared_statement_action_type),
851 Ok(close_prepared_statement_action_type),
852 Ok(create_prepared_substrait_plan_action_type),
853 Ok(begin_transaction_action_type),
854 Ok(end_transaction_action_type),
855 Ok(begin_savepoint_action_type),
856 Ok(end_savepoint_action_type),
857 Ok(cancel_query_action_type),
858 ];
859
860 if let Some(mut custom_actions) = self.list_custom_actions().await {
861 actions.append(&mut custom_actions);
862 }
863
864 let output = futures::stream::iter(actions);
865 Ok(Response::new(Box::pin(output) as Self::ListActionsStream))
866 }
867
868 async fn do_action(
869 &self,
870 request: Request<Action>,
871 ) -> Result<Response<Self::DoActionStream>, Status> {
872 if request.get_ref().r#type == CREATE_PREPARED_STATEMENT {
873 let any = Any::decode(&*request.get_ref().body).map_err(decode_error_to_status)?;
874
875 let cmd: ActionCreatePreparedStatementRequest = any
876 .unpack()
877 .map_err(arrow_error_to_status)?
878 .ok_or_else(|| {
879 Status::invalid_argument(
880 "Unable to unpack ActionCreatePreparedStatementRequest.",
881 )
882 })?;
883 let stmt = self
884 .do_action_create_prepared_statement(cmd, request)
885 .await?;
886 let output = futures::stream::iter(vec![Ok(super::super::r#gen::Result {
887 body: stmt.as_any().encode_to_vec().into(),
888 })]);
889 return Ok(Response::new(Box::pin(output)));
890 } else if request.get_ref().r#type == CLOSE_PREPARED_STATEMENT {
891 let any = Any::decode(&*request.get_ref().body).map_err(decode_error_to_status)?;
892
893 let cmd: ActionClosePreparedStatementRequest = any
894 .unpack()
895 .map_err(arrow_error_to_status)?
896 .ok_or_else(|| {
897 Status::invalid_argument(
898 "Unable to unpack ActionClosePreparedStatementRequest.",
899 )
900 })?;
901 self.do_action_close_prepared_statement(cmd, request)
902 .await?;
903 return Ok(Response::new(Box::pin(futures::stream::empty())));
904 } else if request.get_ref().r#type == CREATE_PREPARED_SUBSTRAIT_PLAN {
905 let any = Any::decode(&*request.get_ref().body).map_err(decode_error_to_status)?;
906
907 let cmd: ActionCreatePreparedSubstraitPlanRequest = any
908 .unpack()
909 .map_err(arrow_error_to_status)?
910 .ok_or_else(|| {
911 Status::invalid_argument(
912 "Unable to unpack ActionCreatePreparedSubstraitPlanRequest.",
913 )
914 })?;
915 self.do_action_create_prepared_substrait_plan(cmd, request)
916 .await?;
917 return Ok(Response::new(Box::pin(futures::stream::empty())));
918 } else if request.get_ref().r#type == BEGIN_TRANSACTION {
919 let any = Any::decode(&*request.get_ref().body).map_err(decode_error_to_status)?;
920
921 let cmd: ActionBeginTransactionRequest = any
922 .unpack()
923 .map_err(arrow_error_to_status)?
924 .ok_or_else(|| {
925 Status::invalid_argument("Unable to unpack ActionBeginTransactionRequest.")
926 })?;
927 let stmt = self.do_action_begin_transaction(cmd, request).await?;
928 let output = futures::stream::iter(vec![Ok(super::super::r#gen::Result {
929 body: stmt.as_any().encode_to_vec().into(),
930 })]);
931 return Ok(Response::new(Box::pin(output)));
932 } else if request.get_ref().r#type == END_TRANSACTION {
933 let any = Any::decode(&*request.get_ref().body).map_err(decode_error_to_status)?;
934
935 let cmd: ActionEndTransactionRequest = any
936 .unpack()
937 .map_err(arrow_error_to_status)?
938 .ok_or_else(|| {
939 Status::invalid_argument("Unable to unpack ActionEndTransactionRequest.")
940 })?;
941 self.do_action_end_transaction(cmd, request).await?;
942 return Ok(Response::new(Box::pin(futures::stream::empty())));
943 } else if request.get_ref().r#type == BEGIN_SAVEPOINT {
944 let any = Any::decode(&*request.get_ref().body).map_err(decode_error_to_status)?;
945
946 let cmd: ActionBeginSavepointRequest = any
947 .unpack()
948 .map_err(arrow_error_to_status)?
949 .ok_or_else(|| {
950 Status::invalid_argument("Unable to unpack ActionBeginSavepointRequest.")
951 })?;
952 let stmt = self.do_action_begin_savepoint(cmd, request).await?;
953 let output = futures::stream::iter(vec![Ok(super::super::r#gen::Result {
954 body: stmt.as_any().encode_to_vec().into(),
955 })]);
956 return Ok(Response::new(Box::pin(output)));
957 } else if request.get_ref().r#type == END_SAVEPOINT {
958 let any = Any::decode(&*request.get_ref().body).map_err(decode_error_to_status)?;
959
960 let cmd: ActionEndSavepointRequest = any
961 .unpack()
962 .map_err(arrow_error_to_status)?
963 .ok_or_else(|| {
964 Status::invalid_argument("Unable to unpack ActionEndSavepointRequest.")
965 })?;
966 self.do_action_end_savepoint(cmd, request).await?;
967 return Ok(Response::new(Box::pin(futures::stream::empty())));
968 } else if request.get_ref().r#type == CANCEL_QUERY {
969 let any = Any::decode(&*request.get_ref().body).map_err(decode_error_to_status)?;
970
971 let cmd: ActionCancelQueryRequest = any
972 .unpack()
973 .map_err(arrow_error_to_status)?
974 .ok_or_else(|| {
975 Status::invalid_argument("Unable to unpack ActionCancelQueryRequest.")
976 })?;
977 let stmt = self.do_action_cancel_query(cmd, request).await?;
978 let output = futures::stream::iter(vec![Ok(super::super::r#gen::Result {
979 body: stmt.as_any().encode_to_vec().into(),
980 })]);
981 return Ok(Response::new(Box::pin(output)));
982 }
983
984 self.do_action_fallback(request).await
985 }
986
987 async fn do_exchange(
988 &self,
989 request: Request<Streaming<FlightData>>,
990 ) -> Result<Response<Self::DoExchangeStream>, Status> {
991 self.do_exchange_fallback(request).await
992 }
993}
994
995pub enum DoPutError {
997 MissingCommand,
999 MissingFlightDescriptor,
1001}
1002impl Display for DoPutError {
1003 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1004 match self {
1005 DoPutError::MissingCommand => {
1006 write!(f, "Command is missing.")
1007 }
1008 DoPutError::MissingFlightDescriptor => {
1009 write!(f, "Flight descriptor is missing.")
1010 }
1011 }
1012 }
1013}
1014
1015fn decode_error_to_status(err: prost::DecodeError) -> Status {
1016 Status::invalid_argument(format!("{err:?}"))
1017}
1018
1019fn arrow_error_to_status(err: arrow_schema::ArrowError) -> Status {
1020 Status::internal(format!("{err:?}"))
1021}
1022
1023pub struct PeekableFlightDataStream {
1069 inner: Peekable<Streaming<FlightData>>,
1070}
1071
1072impl PeekableFlightDataStream {
1073 fn new(stream: Streaming<FlightData>) -> Self {
1074 Self {
1075 inner: stream.peekable(),
1076 }
1077 }
1078
1079 pub fn into_inner(self) -> Streaming<FlightData> {
1083 self.inner.into_inner()
1084 }
1085
1086 pub fn into_peekable(self) -> Peekable<Streaming<FlightData>> {
1090 self.inner
1091 }
1092
1093 pub async fn peek(&mut self) -> Option<&Result<FlightData, Status>> {
1095 Pin::new(&mut self.inner).peek().await
1096 }
1097}
1098
1099impl Stream for PeekableFlightDataStream {
1100 type Item = Result<FlightData, Status>;
1101
1102 fn poll_next(
1103 mut self: Pin<&mut Self>,
1104 cx: &mut std::task::Context<'_>,
1105 ) -> std::task::Poll<Option<Self::Item>> {
1106 self.inner.poll_next_unpin(cx)
1107 }
1108}