@@ -19,35 +19,35 @@ use std::{io::Cursor, time::Duration};
1919
2020use axum:: {
2121 body:: Body ,
22- extract:: { Path , State } ,
22+ extract:: { Json , Path , State } ,
2323 response:: { IntoResponse , Response } ,
2424 routing:: { get, post} ,
2525 Router ,
2626} ;
2727use datafusion:: { arrow:: json:: ArrayWriter , execution:: SendableRecordBatchStream } ;
28- use datafusion_app:: local :: { ExecutionContext , ExecutionOptions , ExecutionResult } ;
28+ use datafusion_app:: { ExecOptions , ExecResult } ;
2929use http:: { HeaderValue , StatusCode } ;
3030use log:: error;
3131use serde:: Deserialize ;
3232use tokio_stream:: StreamExt ;
3333use tower_http:: { timeout:: TimeoutLayer , trace:: TraceLayer } ;
3434use tracing:: info;
3535
36- use crate :: config:: HttpServerConfig ;
36+ use crate :: { config:: HttpServerConfig , execution :: AppExecution } ;
3737
3838#[ derive( Clone ) ]
3939struct ExecutionState {
40- execution : ExecutionContext ,
40+ execution : AppExecution ,
4141 config : HttpServerConfig ,
4242}
4343
4444impl ExecutionState {
45- pub fn new ( execution : ExecutionContext , config : HttpServerConfig ) -> Self {
45+ pub fn new ( execution : AppExecution , config : HttpServerConfig ) -> Self {
4646 Self { execution, config }
4747 }
4848}
4949
50- pub fn create_router ( execution : ExecutionContext , config : HttpServerConfig ) -> Router {
50+ pub fn create_router ( execution : AppExecution , config : HttpServerConfig ) -> Router {
5151 let state = ExecutionState :: new ( execution, config) ;
5252 Router :: new ( )
5353 . route (
@@ -70,14 +70,22 @@ pub fn create_router(execution: ExecutionContext, config: HttpServerConfig) -> R
7070 . with_state ( state)
7171}
7272
73- async fn post_sql_handler ( state : State < ExecutionState > , query : String ) -> Response {
74- let opts = ExecutionOptions :: new ( Some ( state. config . result_limit ) ) ;
75- execute_sql_with_opts ( state, query, opts) . await
73+ #[ derive( Deserialize ) ]
74+ struct PostSqlBody {
75+ query : String ,
76+ #[ serde( default ) ]
77+ flightsql : bool ,
78+ }
79+
80+ async fn post_sql_handler ( state : State < ExecutionState > , Json ( body) : Json < PostSqlBody > ) -> Response {
81+ let opts = ExecOptions :: new ( Some ( state. config . result_limit ) , body. flightsql ) ;
82+ execute_sql_with_opts ( state, body. query , opts) . await
7683}
7784
7885async fn get_catalog_handler ( state : State < ExecutionState > ) -> Response {
79- let opts = ExecutionOptions :: new ( None ) ;
80- execute_sql_with_opts ( state, "SHOW TABLES" . to_string ( ) , opts) . await
86+ let opts = ExecOptions :: new ( None , false ) ;
87+ let sql = "SHOW TABLES" . to_string ( ) ;
88+ execute_sql_with_opts ( state, sql, opts) . await
8189}
8290
8391#[ derive( Deserialize ) ]
@@ -97,29 +105,26 @@ async fn get_table_handler(
97105 table,
98106 } = params;
99107 let sql = format ! ( "SELECT * FROM \" {catalog}\" .\" {schema}\" .\" {table}\" " ) ;
100- let opts = ExecutionOptions :: new ( Some ( state. config . result_limit ) ) ;
108+ let opts = ExecOptions :: new ( Some ( state. config . result_limit ) , false ) ;
101109 execute_sql_with_opts ( state, sql, opts) . await
102110}
103111
112+ // TODO: Maybe rename to something like `response_for_sql`
104113async fn execute_sql_with_opts (
105114 State ( state) : State < ExecutionState > ,
106115 sql : String ,
107- opts : ExecutionOptions ,
116+ opts : ExecOptions ,
108117) -> Response {
109118 info ! ( "Executing sql: {sql}" ) ;
110- let results = state. execution . execute_sql_with_opts ( & sql, opts) . await ;
111- match results {
112- Ok ( ExecutionResult :: RecordBatchStream ( Ok ( batch_stream) ) ) => {
113- batch_stream_to_response ( batch_stream) . await
114- }
115- Err ( e) | Ok ( ExecutionResult :: RecordBatchStream ( Err ( e) ) ) => {
116- error ! ( "Error executing SQL: {}" , e) ;
117- (
118- StatusCode :: BAD_REQUEST ,
119- format ! ( "SQL execution failed: {}" , e) ,
120- )
121- . into_response ( )
122- }
119+ match state. execution . execute_sql_with_opts ( & sql, opts) . await {
120+ Ok ( ExecResult :: RecordBatchStream ( stream) ) => batch_stream_to_response ( stream) . await ,
121+ Ok ( _) => (
122+ StatusCode :: BAD_REQUEST ,
123+ "Execution failed: unknown result type" . to_string ( ) ,
124+ )
125+ . into_response ( ) ,
126+
127+ Err ( e) => ( StatusCode :: BAD_REQUEST , format ! ( "Execution failed: {}" , e) ) . into_response ( ) ,
123128 }
124129}
125130
0 commit comments