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