@@ -25,9 +25,9 @@ use actix_web::{Either, FromRequest, HttpRequest, HttpResponse, Responder};
2525use arrow_array:: RecordBatch ;
2626use bytes:: Bytes ;
2727use chrono:: { DateTime , Utc } ;
28- use datafusion:: common:: tree_node:: TreeNode ;
2928use datafusion:: error:: DataFusionError ;
3029use datafusion:: execution:: context:: SessionState ;
30+ use datafusion:: sql:: sqlparser:: parser:: ParserError ;
3131use futures:: stream:: once;
3232use futures:: { future, Stream , StreamExt } ;
3333use futures_util:: Future ;
@@ -44,11 +44,10 @@ use tracing::{error, warn};
4444
4545use crate :: event:: commit_schema;
4646use crate :: metrics:: QUERY_EXECUTE_TIME ;
47- use crate :: option:: Mode ;
4847use crate :: parseable:: { StreamNotFound , PARSEABLE } ;
4948use crate :: query:: error:: ExecuteError ;
49+ use crate :: query:: { resolve_stream_names, QUERY_SESSION } ;
5050use crate :: query:: { execute, CountsRequest , Query as LogicalQuery } ;
51- use crate :: query:: { TableScanVisitor , QUERY_SESSION } ;
5251use crate :: rbac:: Users ;
5352use crate :: response:: QueryResponse ;
5453use crate :: storage:: ObjectStorageError ;
@@ -81,31 +80,21 @@ pub async fn get_records_and_fields(
8180 query_request : & Query ,
8281 req : & HttpRequest ,
8382) -> Result < ( Option < Vec < RecordBatch > > , Option < Vec < String > > ) , QueryError > {
83+ let tables = resolve_stream_names ( & query_request. query ) ?;
8484 let session_state = QUERY_SESSION . state ( ) ;
8585
86- // get the logical plan and extract the table name
87- let raw_logical_plan = session_state
88- . create_logical_plan ( & query_request. query )
89- . await ?;
90-
9186 let time_range =
9287 TimeRange :: parse_human_time ( & query_request. start_time , & query_request. end_time ) ?;
93- // create a visitor to extract the table name
94- let mut visitor = TableScanVisitor :: default ( ) ;
95- let _ = raw_logical_plan. visit ( & mut visitor) ;
96-
97- let tables = visitor. into_inner ( ) ;
98- update_schema_when_distributed ( & tables) . await ?;
99- let query: LogicalQuery = into_query ( query_request, & session_state, time_range) . await ?;
10088
89+ let query: LogicalQuery =
90+ into_query ( query_request, & session_state, time_range, & tables) . await ?;
10191 let creds = extract_session_key_from_req ( req) ?;
10292 let permissions = Users . get_permissions ( & creds) ;
10393
104- let table_name = query
105- . first_table_name ( )
94+ let table_name = tables
95+ . first ( )
10696 . ok_or_else ( || QueryError :: MalformedQuery ( "No table name found in query" ) ) ?;
107-
108- user_auth_for_datasets ( & permissions, & tables) ?;
97+ user_auth_for_datasets ( & permissions, & tables) . await ?;
10998
11099 let ( records, fields) = execute ( query, & table_name, false ) . await ?;
111100
@@ -121,35 +110,18 @@ pub async fn get_records_and_fields(
121110
122111pub async fn query ( req : HttpRequest , query_request : Query ) -> Result < HttpResponse , QueryError > {
123112 let session_state = QUERY_SESSION . state ( ) ;
124- let raw_logical_plan = match session_state
125- . create_logical_plan ( & query_request. query )
126- . await
127- {
128- Ok ( raw_logical_plan) => raw_logical_plan,
129- Err ( _) => {
130- create_streams_for_querier ( ) . await ?;
131- session_state
132- . create_logical_plan ( & query_request. query )
133- . await ?
134- }
135- } ;
136113 let time_range =
137114 TimeRange :: parse_human_time ( & query_request. start_time , & query_request. end_time ) ?;
138-
139- let mut visitor = TableScanVisitor :: default ( ) ;
140- let _ = raw_logical_plan. visit ( & mut visitor) ;
141- let tables = visitor. into_inner ( ) ;
142- update_schema_when_distributed ( & tables) . await ?;
143- let query: LogicalQuery = into_query ( & query_request, & session_state, time_range) . await ?;
144-
115+ let tables = resolve_stream_names ( & query_request. query ) ?;
116+ let query: LogicalQuery =
117+ into_query ( & query_request, & session_state, time_range, & tables) . await ?;
145118 let creds = extract_session_key_from_req ( & req) ?;
146119 let permissions = Users . get_permissions ( & creds) ;
147120
148- let table_name = query
149- . first_table_name ( )
121+ let table_name = tables
122+ . first ( )
150123 . ok_or_else ( || QueryError :: MalformedQuery ( "No table name found in query" ) ) ?;
151-
152- user_auth_for_datasets ( & permissions, & tables) ?;
124+ user_auth_for_datasets ( & permissions, & tables) . await ?;
153125
154126 let time = Instant :: now ( ) ;
155127
@@ -372,7 +344,7 @@ pub async fn get_counts(
372344 let body = counts_request. into_inner ( ) ;
373345
374346 // does user have access to table?
375- user_auth_for_datasets ( & permissions, & [ body. stream . clone ( ) ] ) ?;
347+ user_auth_for_datasets ( & permissions, & [ body. stream . clone ( ) ] ) . await ?;
376348
377349 // if the user has given a sql query (counts call with filters applied), then use this flow
378350 // this could include filters or group by
@@ -420,11 +392,9 @@ pub async fn update_schema_when_distributed(tables: &Vec<String>) -> Result<(),
420392 // if the mode is query or prism, we need to update the schema in memory
421393 // no need to commit schema to storage
422394 // as the schema is read from memory everytime
423- if PARSEABLE . options . mode == Mode :: Query || PARSEABLE . options . mode == Mode :: Prism {
424- for table in tables {
425- if let Ok ( new_schema) = fetch_schema ( table) . await {
426- commit_schema ( table, Arc :: new ( new_schema) ) ?;
427- }
395+ for table in tables {
396+ if let Ok ( new_schema) = fetch_schema ( table) . await {
397+ commit_schema ( table, Arc :: new ( new_schema) ) ?;
428398 }
429399 }
430400
@@ -520,6 +490,7 @@ pub async fn into_query(
520490 query : & Query ,
521491 session_state : & SessionState ,
522492 time_range : TimeRange ,
493+ tables : & Vec < String > ,
523494) -> Result < LogicalQuery , QueryError > {
524495 if query. query . is_empty ( ) {
525496 return Err ( QueryError :: EmptyQuery ) ;
@@ -532,9 +503,36 @@ pub async fn into_query(
532503 if query. end_time . is_empty ( ) {
533504 return Err ( QueryError :: EmptyEndTime ) ;
534505 }
506+ let raw_logical_plan = match session_state. create_logical_plan ( & query. query ) . await {
507+ Ok ( plan) => plan,
508+ Err ( _) => {
509+ let mut join_set = JoinSet :: new ( ) ;
510+ for stream_name in tables {
511+ let stream_name = stream_name. clone ( ) ;
512+ join_set. spawn ( async move {
513+ let result = PARSEABLE
514+ . create_stream_and_schema_from_storage ( & stream_name)
515+ . await ;
516+
517+ if let Err ( e) = & result {
518+ warn ! ( "Failed to create stream '{}': {}" , stream_name, e) ;
519+ }
520+
521+ ( stream_name, result)
522+ } ) ;
523+ }
524+
525+ while let Some ( result) = join_set. join_next ( ) . await {
526+ if let Err ( join_error) = result {
527+ warn ! ( "Task join error: {}" , join_error) ;
528+ }
529+ }
530+ session_state. create_logical_plan ( & query. query ) . await ?
531+ }
532+ } ;
535533
536534 Ok ( crate :: query:: Query {
537- raw_logical_plan : session_state . create_logical_plan ( & query . query ) . await ? ,
535+ raw_logical_plan,
538536 time_range,
539537 filter_tag : query. filter_tags . clone ( ) ,
540538 } )
@@ -618,6 +616,8 @@ Description: {0}"#
618616 CustomError ( String ) ,
619617 #[ error( "No available queriers found" ) ]
620618 NoAvailableQuerier ,
619+ #[ error( "{0}" ) ]
620+ ParserError ( #[ from] ParserError ) ,
621621}
622622
623623impl actix_web:: ResponseError for QueryError {
0 commit comments